Больше похоже на коррелированный подзапрос
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 здесь
Уточнить дезинформацию
Руководство:
Для типов INNERand и OUTERjoin должно быть указано условие соединения, а именно одно из 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)