Что такое LATERAL
присоединение?
Эта функция была представлена в PostgreSQL 9.3.
Цитирование руководство:
Подзапросам, появляющимся в FROM
, может предшествовать ключевое слово LATERAL
. Это позволяет им ссылаться на столбцы, предоставленные предшествующими FROM
элементами. (Без LATERAL
каждый подзапрос оценивается независимо и поэтому не может ссылаться на какой-либо другой элемент FROM
.)
Табличным функциям, появляющимся в FROM
, также может предшествовать ключевое слово LATERAL
, но для функций ключевое слово является необязательным; аргументы функции в любом случае могут содержать ссылки на столбцы, предоставленные предшествующими FROM
элементами.
Там приведены базовые примеры кода.
Больше похоже на коррелированный подзапрос
LATERAL
join больше похож на коррелированный подзапрос, а не на простой подзапрос, в выражениях справа соединения LATERAL
оцениваются один раз для каждой строки слева от него - точно так же, как коррелированный подзапрос - в то время как простой подзапрос (табличное выражение) оценивается только один раз. (У планировщика запросов есть способы оптимизировать производительность для любого из них.)
Связанный ответ с примерами кода для обеих сторон, решая ту же проблему:
Для возврата более чем одного столбца соединение LATERAL
обычно проще, чище и быстрее.
Также помните, что эквивалентом коррелированного подзапроса является LEFT JOIN LATERAL ... ON true
:
Что не может сделать подзапрос
Есть вещи, которые LATERAL
может выполнять соединение, но (коррелированный) подзапрос не может (легко). Коррелированный подзапрос может возвращать только одно значение, а не несколько столбцов и не несколько строк - за исключением простых вызовов функций (которые умножают строки результатов, если они возвращают несколько строк). Но даже некоторые функции, возвращающие набор, разрешены только в предложении FROM
. Как unnest()
с несколькими параметрами в Postgres 9.4 или новее. Руководство:
Это разрешено только в предложении FROM
;
Итак, это работает, но не может (легко) быть заменено подзапросом:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
Запятая (,
) в предложении FROM
- это краткое обозначение для CROSS JOIN
.
LATERAL
автоматически предполагается для табличных функций.
Об особом случае UNNEST( array_expression [, ... ] )
:
Функции, возвращающие множество, в списке SELECT
Вы также можете напрямую использовать функции возврата набора, такие как unnest()
в списке SELECT
. Раньше это проявляло удивительное поведение с более чем одной такой функцией в одном SELECT
списке до Postgres 9.6. Но, наконец, он был очищен с помощью Postgres 10 и теперь является допустимой альтернативой (даже если это не стандартный SQL). Видеть:
Основываясь на приведенном выше примере:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Сравнение:
dbfiddle для pg 9.6 здесь
dbfiddle для pg 10 здесь
Разъяснить дезинформацию
Руководство:
Для типов соединения INNER
и OUTER
необходимо указать условие соединения, а именно одно из NATURAL
, ON
join_condition или USING
(join_column сильный> [, ...]). Значение см. Ниже.
Для CROSS JOIN
ни один из этих пунктов не может появляться.
Итак, эти два запроса действительны (даже если они не особенно полезны):
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t ON TRUE;
SELECT *
FROM tbl t, LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Пока этого нет:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Вот почему пример кода Andomar верен (CROSS JOIN
не требует условия соединения) и Аттилы is не было.
person
Erwin Brandstetter
schedule
17.02.2015
apply
в SQL Server совпадает сlateral
из стандарта SQL) - person a_horse_with_no_name   schedule 17.02.2015LATERAL
принадлежит следующей производной таблице (подзапросу), т.е. это не тип JOIN. - person jarlh   schedule 03.05.2021