聚合函数组合器
聚合函数的名称可以附加一个后缀。这将改变聚合函数的工作方式。
-If
后缀 -If 可以附加到任何聚合函数的名称。在这种情况下,聚合函数接受一个额外的参数——一个条件(Uint8 类型)。聚合函数仅处理触发条件的行。如果条件未被触发,即使一次也不会触发,则返回默认值(通常为零或空字符串)。
示例: sumIf(column, cond)
, countIf(cond)
, avgIf(x, cond)
, quantilesTimingIf(level1, level2)(x, cond)
, argMinIf(arg, val, cond)
等等。
使用条件聚合函数,您可以一次计算多个条件的聚合,而无需使用子查询和 JOIN
。例如,条件聚合函数可以用于实现分段比较功能。
-Array
后缀 -Array 可以附加到任何聚合函数。在这种情况下,聚合函数接受 'Array(T)' 类型(数组)而不是 'T' 类型参数。如果聚合函数接受多个参数,这些参数必须是相同长度的数组。在处理数组时,聚合函数像原始聚合函数一样在所有数组元素上工作。
示例 1: sumArray(arr)
- 计算所有 'arr' 数组的所有元素的总和。在此示例中,它可以更简单地写为: sum(arraySum(arr))
。
示例 2: uniqArray(arr)
– 计算所有 'arr' 数组中唯一元素的数量。这可以通过更简单的方式完成: uniq(arrayJoin(arr))
,但并非总是可以将 'arrayJoin' 添加到查询中。
-If 和 -Array 可以组合。但是,'Array' 必须首先出现,然后是 'If'。示例: uniqArrayIf(arr, cond)
, quantilesTimingArrayIf(level1, level2)(arr, cond)
。由于这个顺序,'cond' 参数不会是数组。
-Map
后缀 -Map 可以附加到任何聚合函数。这会创建一个聚合函数,该函数将 Map 类型作为参数,并使用指定的聚合函数分别聚合地图每个键的值。结果也是 Map 类型。
示例
-SimpleState
如果您应用这个组合器,聚合函数返回相同的值,但类型不同。这是一个 SimpleAggregateFunction(...),可以存储在表中,以便与 AggregatingMergeTree 表一起使用。
语法
参数
x
— 聚合函数参数。
返回值
聚合函数的 SimpleAggregateFunction(...)
类型的值。
示例
查询:
结果:
-State
如果您应用这个组合器,聚合函数不返回结果值(例如,uniq 函数的唯一值计数),而是返回聚合的中间状态(对于 uniq
,这是用于计算唯一值数量的哈希表)。这是一个 AggregateFunction(...)
,可以用于后续处理或存储在表中以便稍后完成聚合。
请注意,由于中间状态中的数据顺序可能会变化,-MapState 不是对同一数据的固定值,但这不会影响数据的摄取。
要处理这些状态,请使用:
- AggregatingMergeTree 表引擎。
- finalizeAggregation 函数。
- runningAccumulate 函数。
- -Merge 组合器。
- -MergeState 组合器。
-Merge
如果您应用这个组合器,聚合函数将中间聚合状态作为参数,合并状态以完成聚合,并返回结果值。
-MergeState
以与 -Merge 组合器相同的方式合并中间聚合状态。然而,它不返回结果值,而是返回一个中间聚合状态,类似于 -State 组合器。
-ForEach
将适用于表的聚合函数转换为适用于数组的聚合函数,该函数聚合相应数组项并返回结果数组。例如,sumForEach
对于数组 [1, 2]
,[3, 4, 5]
和 [6, 7]
在将相应数组项相加后返回结果 [10, 13, 5]
。
-Distinct
每个唯一的参数组合将仅聚合一次。重复的值将被忽略。
示例: sum(DISTINCT x)
(或 sumDistinct(x)
), groupArray(DISTINCT x)
(或 groupArrayDistinct(x)
), corrStable(DISTINCT x, y)
(或 corrStableDistinct(x, y)
)等等。
-OrDefault
改变聚合函数的行为。
如果聚合函数没有输入值,使用这个组合器将返回其返回数据类型的默认值。适用于可以接受空输入数据的聚合函数。
-OrDefault
可以与其他组合器一起使用。
语法
参数
x
— 聚合函数参数。
返回值
如果没有任何内容可聚合,返回聚合函数返回类型的默认值。
类型取决于使用的聚合函数。
示例
查询:
结果:
此外,-OrDefault
还可以与其他组合器一起使用。当聚合函数不接受空输入时,这非常有用。
查询:
结果:
-OrNull
改变聚合函数的行为。
该组合器将聚合函数的结果转换为 Nullable 数据类型。如果聚合函数没有可计算的值,则返回 NULL。
-OrNull
可以与其他组合器一起使用。
语法
参数
x
— 聚合函数参数。
返回值
- 聚合函数的结果,转换为
Nullable
数据类型。 - 如果没有内容可以聚合,则返回
NULL
。
类型: Nullable(聚合函数返回类型)
。
示例
在聚合函数的末尾添加 -orNull
。
查询:
结果:
此外,-OrNull
还可以与其他组合器一起使用。当聚合函数不接受空输入时,这非常有用。
查询:
结果:
-Resample
允许您将数据分成组,然后分别聚合这些组中的数据。组是通过将一列的值划分为区间来创建的。
参数
start
— 所需区间的开始值,用于resampling_key
值。stop
— 所需区间的结束值,用于resampling_key
值。整个区间不包括stop
值[start, stop)
。step
— 将整个区间分成子区间的步长。aggFunction
在每个子区间上独立执行。resampling_key
— 用于将数据分隔成区间的列。aggFunction_params
—aggFunction
参数。
返回值
- 每个子区间的
aggFunction
结果数组。
示例
考虑包含以下数据的 people
表:
让我们获取年龄在区间 [30,60)
和 [60,75)
内的人的名字。由于我们对年龄使用整数表示,因此我们获得的年龄在 [30, 59]
和 [60,74]
区间内。
要将名字聚合成数组,我们使用 groupArray 聚合函数。它接受一个参数。在我们的例子中,参数是 name
列。groupArrayResample
函数应使用 age
列根据年龄聚合姓名。为了定义所需的区间,我们传入 30, 75, 30
参数到 groupArrayResample
函数中。
考虑结果。
John
不在样本中,因为他太年轻。其他人根据指定的年龄区间分布。
现在让我们计算指定年龄区间内的总人数和他们的平均薪资。
-ArgMin
后缀 -ArgMin 可以附加到任何聚合函数的名称。在这种情况下,聚合函数接受一个额外参数,该参数应该是任何可比较的表达式。聚合函数仅处理具有所需额外表达式的最小值的行。
示例: sumArgMin(column, expr)
, countArgMin(expr)
, avgArgMin(x, expr)
等等。
-ArgMax
类似于后缀 -ArgMin,但仅处理具有所需额外表达式的最大值的行。