Лямбда-выражения#

Лямбда-выражения — это анонимные функции, которые передаются как аргументы в SQL-функции высшего порядка.

Лямбда-выражения записываются с помощью ->:

x -> x + 1
(x, y) -> x + y
x -> regexp_like(x, 'a+')
x -> x[1] / x[2]
x -> IF(x > 0, x, -x)
x -> COALESCE(x, 0)
x -> CAST(x AS JSON)
x -> x + TRY(1 / 0)

Ограничения#

Большинство SQL-выражений можно использовать в теле лямбда-выражения, за несколькими исключениями:

  • Подзапросы не поддерживаются: x -> 2 + (SELECT 3)

  • Агрегации не поддерживаются: x -> max(y)

Примеры#

Получите элементы столбца массива, возведенные в квадрат, с помощью transform():

SELECT numbers,
       transform(numbers, n -> n * n) as squared_numbers
FROM (
    VALUES
        (ARRAY[1, 2]),
        (ARRAY[3, 4]),
        (ARRAY[5, 6, 7])
) AS t(numbers);
  numbers  | squared_numbers
-----------+-----------------
 [1, 2]    | [1, 4]
 [3, 4]    | [9, 16]
 [5, 6, 7] | [25, 36, 49]
(3 rows)

Функцию transform() также можно использовать, чтобы безопасно привести элементы массива к строкам:

SELECT transform(prices, n -> TRY_CAST(n AS VARCHAR) || '$') as price_tags
FROM (
    VALUES
        (ARRAY[100, 200]),
        (ARRAY[30, 4])
) AS t(prices);
  price_tags
--------------
 [100$, 200$]
 [30$, 4$]
(2 rows)

Помимо обрабатываемого столбца массива, внутри лямбда-выражения также можно захватывать и другие столбцы. Следующий запрос демонстрирует эту возможность для вычисления значений линейной функции f(x) = ax + b с помощью transform():

SELECT xvalues,
       a,
       b,
       transform(xvalues, x -> a * x + b) as linear_function_values
FROM (
    VALUES
        (ARRAY[1, 2], 10, 5),
        (ARRAY[3, 4], 4, 2)
) AS t(xvalues, a, b);
 xvalues | a  | b | linear_function_values
---------+----+---+------------------------
 [1, 2]  | 10 | 5 | [15, 25]
 [3, 4]  |  4 | 2 | [14, 18]
(2 rows)

Найдите элементы массива, содержащие хотя бы одно значение больше 100, с помощью any_match():

SELECT numbers
FROM (
    VALUES
        (ARRAY[1,NULL,3]),
        (ARRAY[10,20,30]),
        (ARRAY[100,200,300])
) AS t(numbers)
WHERE any_match(numbers, n ->  COALESCE(n, 0) > 100);
-- [100, 200, 300]

Сделайте первую букву первого слова в строке заглавной с помощью regexp_replace():

SELECT regexp_replace('once upon a time ...', '^(\w)(\w*)(\s+.*)$',x -> upper(x[1]) || x[2] || x[3]);
-- Once upon a time ...

Лямбда-выражения также можно применять в агрегатных функциях. Следующий запрос — пример намеренно усложненного вычисления суммы всех элементов столбца с использованием reduce_agg():

SELECT reduce_agg(value, 0, (a, b) -> a + b, (a, b) -> a + b) sum_values
FROM (
    VALUES (1), (2), (3), (4), (5)
) AS t(value);
-- 15