高阶函数是什么
高阶函数用 lambda 表达式对数组做映射、过滤与规约,写法是 func(x -> 表达式, 数组)。常用的有 arrayMap、arrayFilter、arrayReduce、arrayExists、arrayAll、arrayCount;规约用 arrayReduce('sum', arr) 这类形式指定聚合函数名。它适合在 SQL 内完成轻量数据处理,省掉把数据拉到应用层再算的往返,也便于把计算逻辑留在查询里统一版本。
基本信息
| 写法 | func(x -> 表达式, 数组[, 参数]) |
|---|---|
| 映射与过滤 | arrayMap / arrayFilter / arrayExists / arrayAll / arrayCount |
| 规约 | arrayReduce('sum', arr)、arrayReduce('avg', arr) |
| 相关数组函数 | arraySort、arrayDistinct、arrayJoin |
| 所属系统 | ClickHouse |
典型使用场景
- 批量换算:对数组里每个值做单位转换或格式化
- 条件筛选:挑出满足条件的元素再做统计
- 判存在:判断数组里是否有满足条件的元素
- 规约统计:对数组直接求和、求平均或去重计数
- 标签清洗:把标签数组统一大小写或去重后输出
常用写法
常用写法
SELECT arrayMap(x -> x * 10, [1, 2, 3]) AS mapped; -- 逐元素映射
SELECT arrayFilter(x -> x % 2 = 0, [1, 2, 3, 4]) AS evens; -- 过滤出偶数
SELECT arrayReduce('sum', [1, 2, 3]) AS total; -- 规约求和
SELECT arrayExists(x -> x > 3, [1, 2, 3, 4]) AS has_big; -- 是否存在更大元素
SELECT arraySort(arrayDistinct([3, 1, 3, 2])) AS uniq_sorted; -- 去重后排序常用函数读法
| 函数 | 作用 | 返回 |
|---|---|---|
| arrayMap | 逐元素映射 | 与原数组等长 |
| arrayFilter | 条件过滤 | 长度不定的数组 |
| arrayReduce | 规约聚合 | 单值 |
| arrayExists | 是否存在满足条件 | 0 或 1 |
| arrayAll | 是否全部满足 | 0 或 1 |
lambda 里可以引用外层列形成闭包,例如 arrayMap(x -> x + base, arr),但嵌套层级过深会明显影响可读性,复杂逻辑不如拆成多步。
lambda 的参数名与列名重名时会遮蔽外层列,取一个不会冲突的参数名更稳妥。
对每行展开大数组会显著放大内存占用,使用前先评估数组的平均长度与最大值,避免把单行处理变成内存热点。
arrayJoin 常与高阶函数配合:先用 arrayFilter 挑出需要的元素再展开成多行,能显著减少无谓的行数放大。
两个长度不等的数组参与同一次逐元素计算时,多数数组函数以较短的一侧为准,结果长度容易与直觉不符;需要严格对齐时先用 arrayResize 补齐,具体行为以对应函数的官方说明为准。