Lambda 函数使得在查询中使用更复杂和灵活的表达式成为可能。
DuckDB 支持多个标量函数,这些函数操作于 LIST
s 并接受 lambda 函数作为参数,
形式为 (parameter1, parameter2, ...) -> expression
。
如果 lambda 函数只有一个参数,那么括号可以省略。
参数可以有任何名称。
例如,以下都是有效的 lambda 函数:
param -> param > 1
s -> contains(concat(s, 'DB'), 'duck')
(x, y) -> x + y
接受Lambda函数的标量函数
Name | Description |
---|---|
list_transform(list, lambda) |
返回一个列表,该列表是将lambda函数应用于输入列表的每个元素的结果。 |
list_filter(list, lambda) |
从输入列表中构造一个新列表,该列表包含那些使lambda函数返回true 的元素。 |
list_reduce(list, lambda) |
通过在一个运行结果和下一个列表元素上执行lambda函数,将输入列表的所有元素减少为单个值。列表必须至少有一个元素——目前不支持使用初始累加器值。 |
list_transform(list, lambda)
描述 | 返回一个列表,该列表是将lambda函数应用于输入列表的每个元素的结果。有关更多信息,请参阅Transform。 |
示例 | list_transform([4, 5, 6], x -> x + 1) |
结果 | [5, 6, 7] |
别名 | array_transform , apply , list_apply , array_apply |
list_filter(list, lambda)
描述 | 从输入列表中构造一个列表,该列表包含那些使lambda函数返回true 的元素。更多信息,请参见Filter。 |
示例 | list_filter([4, 5, 6], x -> x > 4) |
结果 | [5, 6] |
别名 | array_filter , filter |
list_reduce(list, lambda)
描述 | 通过对运行结果和下一个列表元素执行lambda函数,将输入列表的所有元素减少为单个值。列表必须至少有一个元素——目前不支持使用初始累加器值。有关更多信息,请参见Reduce。 |
示例 | list_reduce([4, 5, 6], (x, y) -> x + y) |
结果 | 15 |
别名 | array_reduce , reduce |
Nesting
所有标量函数都可以任意嵌套。
嵌套的lambda函数用于获取列表中所有偶数元素的平方:
SELECT list_transform(
list_filter([0, 1, 2, 3, 4, 5], x -> x % 2 = 0),
y -> y * y
);
[0, 4, 16]
嵌套的lambda函数,用于将第一个列表的每个元素添加到第二个列表的总和中:
SELECT list_transform(
[1, 2, 3],
x -> list_reduce([4, 5, 6], (a, b) -> a + b) + x
);
[16, 17, 18]
作用域
Lambda 函数按照以下顺序确认作用域规则:
- 内部lambda参数
- 外部 lambda 参数
- 列名
- 宏参数
CREATE TABLE tbl (x INTEGER);
INSERT INTO tbl VALUES (10);
SELECT apply([1, 2], x -> apply([4], x -> x + tbl.x)[1] + x) FROM tbl;
[15, 16]
索引作为参数
所有lambda函数都接受一个可选的额外参数,该参数表示当前元素的索引。 这始终是lambda函数的最后一个参数,并且是基于1的(即第一个元素的索引为1)。
获取所有大于其索引的元素:
SELECT list_filter([1, 3, 1, 5], (x, i) -> x > i);
[3, 5]
Transform
签名: list_transform(list, lambda)
描述: list_transform
返回一个列表,该列表是将 lambda 函数应用于输入列表的每个元素的结果。
别名:
array_transform
apply
list_apply
array_apply
不包括索引的参数数量: 1
返回类型: 由lambda函数的返回类型定义
Examples
将每个列表元素增加一:
SELECT list_transform([1, 2, NULL, 3], x -> x + 1);
[2, 3, NULL, 4]
转换字符串:
SELECT list_transform(['Duck', 'Goose', 'Sparrow'], s -> concat(s, 'DB'));
[DuckDB, GooseDB, SparrowDB]
将lambda函数与其他函数结合使用:
SELECT list_transform([5, NULL, 6], x -> coalesce(x, 0) + 1);
[6, 1, 7]
Filter
签名: list_filter(list, lambda)
描述:
从输入列表中构造一个列表,该列表包含那些lambda函数返回true
的元素。
DuckDB必须能够将lambda函数的返回类型转换为BOOL
。
别名:
array_filter
filter
Number of parameters excluding indexes: 1
返回类型: 与输入列表相同的类型
Examples
过滤掉负值:
SELECT list_filter([5, -6, NULL, 7], x -> x > 0);
[5, 7]
能被2和5整除:
SELECT list_filter(
list_filter([2, 4, 3, 1, 20, 10, 3, 30], x -> x % 2 = 0),
y -> y % 5 = 0
);
[20, 10, 30]
结合 range(...)
来构建列表:
SELECT list_filter([1, 2, 3, 4], x -> x > #1) FROM range(4);
[1, 2, 3, 4]
[2, 3, 4]
[3, 4]
[4]
[]
Reduce
签名: list_reduce(list, lambda)
描述: 标量函数返回一个单一值, 该值是将lambda函数应用于输入列表的每个元素的结果。 从第一个元素开始, 然后重复将lambda函数应用于前一次应用的结果和列表的下一个元素。 列表必须至少有一个元素。
别名:
array_reduce
reduce
不包括索引的参数数量: 2
返回类型: 输入列表元素的类型
Examples
所有列表元素的总和:
SELECT list_reduce([1, 2, 3, 4], (x, y) -> x + y);
10
只有当列表元素大于2时才进行累加:
SELECT list_reduce(list_filter([1, 2, 3, 4], x -> x > 2), (x, y) -> x + y);
7
连接所有列表元素:
SELECT list_reduce(['DuckDB', 'is', 'awesome'], (x, y) -> concat(x, ' ', y));
DuckDB is awesome