⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
Lambda 函数

已弃用 DuckDB 1.3.0 弃用了旧的 lambda 单箭头语法(x -> x + 1),转而支持 Python 风格的语法(lambda x : x + 1)。

DuckDB 1.3.0 还引入了一个新设置来配置 lambda 语法。

SET lambda_syntax = 'DEFAULT';
SET lambda_syntax = 'ENABLE_SINGLE_ARROW';
SET lambda_syntax = 'DISABLE_SINGLE_ARROW';

目前,DEFAULT 启用两种语法风格,即旧的单箭头语法和 Python 风格的语法。

DuckDB 1.4.0 将是最后一个在未明确启用单箭头语法的情况下支持它的版本。

DuckDB 1.5.0 默认禁用单箭头语法。

DuckDB 1.6.0 将移除 lambda_syntax 标志并完全弃用单箭头语法,因此旧的行为将不再可能。

Lambda 函数允许在查询中使用更复杂、更灵活的表达式。DuckDB 支持多种作用于 LIST(列表)的标量函数,并接受形如 lambda 参数1, 参数2, ... : 表达式 的 lambda 函数作为参数。如果 lambda 函数只有一个参数,则可以省略括号。参数可以有任何名称。例如,以下都是有效的 lambda 函数:

  • lambda param : param > 1
  • lambda s : contains(concat(s, 'DB'), 'duck')
  • lambda acc, x : acc + x

接受 Lambda 函数的标量函数

名称 描述
list_transform(list, lambda(x)) 返回一个列表,该列表是应用 lambda 函数到输入列表的每个元素的结果。返回类型由 lambda 函数的返回类型定义。请参阅 list_transform 示例
list_filter(list, lambda(x)) 从输入列表中筛选出 lambda 函数返回 true 的元素,并构造一个新列表。DuckDB 必须能够将 lambda 函数的返回类型转换为 BOOLlist_filter 的返回类型与输入列表相同。请参阅 list_filter 示例
list_reduce(list, lambda(x, y)[, initial_value] 通过在当前结果和下一个列表元素上执行 lambda 函数,将输入列表的所有元素归约(reduce)为一个单一的标量值。lambda 函数有一个可选的 initial_value 参数。请参阅 list_reduce 示例或详细信息。

list_transform(list, lambda(x))

描述 返回一个列表,该列表是应用 lambda 函数到输入列表的每个元素的结果。返回类型由 lambda 函数的返回类型定义。请参阅 list_transform 示例
示例 list_transform([4, 5, 6], lambda x : x + 1)
结果 [5, 6, 7]
别名 array_transform, apply, list_apply, array_apply

list_filter(list, lambda(x))

描述 从输入列表中筛选出 lambda 函数返回 true 的元素,并构造一个新列表。DuckDB 必须能够将 lambda 函数的返回类型转换为 BOOLlist_filter 的返回类型与输入列表相同。请参阅 list_filter 示例
示例 list_filter([4, 5, 6], lambda x : x > 4)
结果 [5, 6]
别名 array_filter, filter

list_reduce(list, lambda(x, y)[, initial_value]

描述 通过在当前结果和下一个列表元素上执行 lambda 函数,将输入列表的所有元素归约(reduce)为一个单一的标量值。lambda 函数有一个可选的 initial_value 参数。请参阅 list_reduce 示例或详细信息。
示例 list_reduce([1, 2, 3], lambda x, y : x + y, 100)
结果 106
别名 array_reduce, reduce

嵌套 Lambda 函数

所有标量函数都可以任意嵌套。例如,嵌套 lambda 函数以获取列表偶数元素的平方:

SELECT list_transform(
        list_filter([0, 1, 2, 3, 4, 5], lambda x: x % 2 = 0),
        lambda y: y * y
    );
[0, 4, 16]

嵌套 lambda 函数将第一个列表的每个元素添加到第二个列表的和中。

SELECT list_transform(
        [1, 2, 3],
        lambda x :
            list_reduce([4, 5, 6], lambda a, b: a + b) + x
    );
[16, 17, 18]

作用域

Lambda 函数遵循以下作用域规则:

  • 内部 lambda 参数
  • 外部 lambda 参数
  • 列名
  • 宏参数
CREATE TABLE tbl (x INTEGER);
INSERT INTO tbl VALUES (10);
SELECT list_apply(
            [1, 2],
            lambda x: list_apply([4], lambda x: x + tbl.x)[1] + x
    )
FROM tbl;
[15, 16]

索引作为参数

所有 lambda 函数都接受一个可选的额外参数,该参数表示当前元素的索引。这始终是 lambda 函数的最后一个参数(例如,(x, i) 中的 i),并且是基于 1 的索引(即,第一个元素的索引是 1)。

获取所有大于其索引的元素

SELECT list_filter([1, 3, 1, 5], lambda x, i: x > i);
[3, 5]

示例

list_transform 示例

将每个列表元素加一

SELECT list_transform([1, 2, NULL, 3], lambda x: x + 1);
[2, 3, NULL, 4]

转换字符串

SELECT list_transform(['Duck', 'Goose', 'Sparrow'], lambda s: concat(s, 'DB'));
[DuckDB, GooseDB, SparrowDB]

将 lambda 函数与其他函数结合

SELECT list_transform([5, NULL, 6], lambda x: coalesce(x, 0) + 1);
[6, 1, 7]

list_filter 示例

过滤掉负值

SELECT list_filter([5, -6, NULL, 7], lambda x: x > 0);
[5, 7]

可被 2 和 5 整除

SELECT list_filter(
        list_filter([2, 4, 3, 1, 20, 10, 3, 30], lambda x: x % 2 = 0),
        lambda y: y % 5 = 0
    );
[20, 10, 30]

结合 range(...) 构造列表

SELECT list_filter([1, 2, 3, 4], lambda x: x > #1) FROM range(4);
[1, 2, 3, 4]
[2, 3, 4]
[3, 4]
[4]

list_reduce 示例

所有列表元素的和

SELECT list_reduce([1, 2, 3, 4], lambda acc, x: acc + x);
10

仅当列表元素大于 2 时才求和

SELECT list_reduce(
        list_filter([1, 2, 3, 4], lambda x: x > 2),
        lambda acc, x: acc + x
    );
7

连接所有列表元素

SELECT list_reduce(['DuckDB', 'is', 'awesome'], lambda acc, x: concat(acc, ' ', x));
DuckDB is awesome

连接带索引的元素,无初始值

SELECT list_reduce(
        ['a', 'b', 'c', 'd'],
        lambda x, y, i: x || ' - ' || CAST(i AS VARCHAR) || ' - ' || y
    );
a - 2 - b - 3 - c - 4 - d

连接带索引的元素,有初始值

SELECT list_reduce(
        ['a', 'b', 'c', 'd'],
        lambda x, y, i: x || ' - ' || CAST(i AS VARCHAR) || ' - ' || y, 'INITIAL'
    );
INITIAL - 1 - a - 2 - b - 3 - c - 4 - d

限制

lambda 表达式中目前不支持子查询。例如:

SELECT list_apply([1, 2, 3], lambda x: (SELECT 42) + x);
Binder Error:
subqueries in lambda expressions are not supported