首页/数据/NoSQL 速查/高阶函数与 lambda 表达式
ClickHouse56 条

高阶函数与 lambda 表达式

高阶函数用 lambda 表达式对数组做映射、过滤与规约:arrayMap、arrayFilter、arrayReduce、arrayExists、arrayAll 等,适合在 SQL 内完成轻量数据处理。

NoSQL 速查数据更新于 2026-10-13

高阶函数是什么

高阶函数用 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 补齐,具体行为以对应函数的官方说明为准。

易错点

  • lambda 参数名与列名相同会遮蔽外部列,取不同名字更稳
  • 对每行展开大数组会显著放大内存,先评估数组平均长度
  • arrayJoin 会改变结果行数(一行数组展开成多行),与 arrayMap 混用时要确认行数符合预期
  • 把复杂逻辑全塞进 lambda 让 SQL 难以维护,能在应用层提前算好的数据不必都放进查询

数据来源与参考

  • ClickHouse Docs: Higher-order functions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌