ARRAY_AGGREGATE 函数
简介
ARRAY_AGGREGATE 函数是一种高阶数组聚合函数,类似于函数式编程中的 reduce / fold 操作。它接收一个数组、一个初始值和一个 merge lambda 表达式,从初始值开始,依次将数组中的每个元素与累加器通过 merge lambda 进行合并,最终返回聚合结果。
语法
array_aggregate(array, initial_value, merge_lambda)
参数说明
array: 输入的数组,类型为 ARRAY<E>,其中 E 可以是任意数据类型。
initial_value: 聚合的初始值(累加器初始状态),类型为 R,可以是任意数据类型。
merge_lambda: 合并 lambda 表达式,格式为 (acc, x) -> expr,其中 acc 为当前累加器值(类型 R),x 为数组中的当前元素(类型 E),expr 为合并后的新累加器值(类型 R)。
返回结果
返回类型与初始值 initial_value 的类型一致(类型 R),即 merge lambda 表达式的返回值类型。
使用示例
-
计算数组元素之和:
SELECT array_aggregate(array(1, 2, 3), 0, (acc, x) -> acc + x);
-- 输出结果:6
-
将嵌套数组合并为一个去重后的数组:
SELECT array_aggregate(a, array(date '1999-01-01'), (acc, x) -> array_union(acc, x))
FROM VALUES
(array(array(date '2020-10-10', date '2020-10-10'), array(date '2011-11-11'))),
(array(array(date '2020-11-11')))
AS t(a);
-- 输出结果:
-- [1999-01-01,2020-10-10,2011-11-11]
-- [1999-01-01,2020-11-11]
-
统计嵌套数组中去重后的元素总数:
SELECT array_aggregate(a, 0, (acc, x) -> acc + array_size(array_distinct(x)))
FROM VALUES
(array(array(date '2020-10-10', date '2020-10-10'), array(date '2011-11-11'))),
(array(array(date '2020-11-11')))
AS t(a);
-- 输出结果:
-- 2
-- 1
-
使用布尔累加器判断数组中所有元素是否满足条件:
SELECT array_aggregate(a, true,
(acc, x) -> acc AND (x > date '1990-01-01') AND (year(x) % 2 == 0)
)
FROM VALUES
(array(date '2020-10-10', date '1998-01-01'))
AS t(a);
-- 输出结果:true
-
当数组元素包含无法转换的值时,NULL 会通过 lambda 传播:
SELECT array_aggregate(a, 0L,
(acc, x) -> acc + coalesce(cast(x AS BIGINT), NULL)
)
FROM VALUES
(array('123', 'abc', '456'))
AS t(a);
-- 输出结果:NULL
注意事项
- 使用 ARRAY_AGGREGATE 函数前,需要开启 JIT 代码生成:
SET cz.sql.codegen.enable = TRUE;。
- 当输入数组为 NULL 时,返回结果为 NULL。
- 当数组为空时,返回初始值
initial_value。
- merge lambda 中如果产生 NULL 值,NULL 会继续参与后续迭代,可能导致最终结果为 NULL。建议在 lambda 中使用
COALESCE 等函数处理 NULL 值。
- 初始值的类型决定了累加器和最终返回值的类型,请确保 merge lambda 的返回类型与初始值类型兼容。