Больше похоже на коррелированный подзапрос
LATERAL
Присоединиться (Postgres 9.3 или более поздней версии) больше похож на коррелированных подзапросов , а не простой подзапроса. Как указывал Андомар , функция или подзапрос справа от LATERAL
объединения должен оцениваться один раз для каждой строки слева от него - так же, как коррелированный подзапрос - в то время как простой подзапрос (табличное выражение) оценивается только один раз . (Однако в планировщике запросов есть способы оптимизировать производительность для любого из них.)
Этот связанный ответ содержит примеры кода для обеих сторон, решая одну и ту же проблему:
Для возвращения более одного столбца , LATERAL
присоединиться , как правило , проще, чище и быстрее.
Также помните, что эквивалент коррелированного подзапроса LEFT JOIN LATERAL ... ON true
:
Прочтите руководство на LATERAL
Это более авторитетно, чем все, что мы собираемся вставить в ответы здесь:
То, что подзапрос не может сделать
Там являются вещи , которые 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
and и OUTER
join должно быть указано условие соединения, а именно одно из 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 был недействителен.
apply
совпадаетlateral
со стандартом SQL)