Какво е a LATERAL да се присъединя?
Функцията е въведена с PostgreSQL 9.3. Ръководството:
Подзаявки, които се появяват в
FROMможе да се предшества от ключовата думаLATERAL. Това им позволява да се позовават на колони, предоставени от предходнияFROMартикули. (БезLATERAL, всяка подзаявка се оценява независимо и така не може да се препраща към другFROMт.)Функциите на таблицата се появяват в
FROMможе също да се предшества от ключовата думаLATERAL, но за функции ключовата дума не е задължителна; Аргументите на функцията могат да съдържат препратки към колони, предоставени с предхождащFROMелементи във всеки случай.
Там са дадени основни примери за код.
По-скоро корелиран подзаявка
A LATERAL присъединяването е по-скоро като корелирана подзаявка, а не обикновена подзаявка, в тези изрази вдясно от LATERAL join се оценяват веднъж за всеки ред вляво от него - точно като корелирани подзаявка - докато обикновена подзаявка (израз на таблица) се оценява веднъж само. (Все пак инструментът за планиране на заявки има начини да оптимизира производителността и за двете.)
Свързан отговор с примери за код и за двете един до друг, решавайки един и същ проблем:
- Оптимизирайте заявката GROUP BY, за да извлечете последния ред на потребител
За връщане на повече от една колона , LATERAL присъединяването обикновено е по-просто, по-чисто и по-бързо.
Освен това не забравяйте, че еквивалентът на корелирана подзаявка е LEFT JOIN LATERAL ... ON true :
- Извикване на функция за връщане на набор с аргумент на масив няколко пъти
Неща, които подзаявката не може да направи
Има има неща, които LATERAL join може да направи, но (корелирана) подзаявка не може (лесно). Корелираната подзаявка може да върне само една стойност, а не множество колони и не множество редове - с изключение на извиквания на голи функции (които умножават редовете с резултати, ако връщат няколко реда). Но дори определени функции за връщане на набори са разрешени само в 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 [, ... ] ) :
- Как да декларирате, че функция за връщане на набор да бъде разрешена само в клаузата FROM?
Връщащи функции функции в SELECT списък
Можете също да използвате функции за връщане на набори като unnest() в SELECT списък директно. Това се използва за показване на изненадващо поведение с повече от една такава функция в същия SELECT списък до Postgres 9.6. Но най-накрая е саниран с Postgres 10 и сега е валидна алтернатива (дори и да не е стандартен SQL). Вижте:
- Какво е очакваното поведение за множество функции, връщащи набор в клауза SELECT?
Въз основа на горния пример:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Сравнение:
dbfiddle за стр. 9.6 тук
dbfiddle за стр. 10 тук
Изяснете дезинформацията
Ръководството:
За
INNERиOUTERтипове на присъединяване, условието за присъединяване трябва да бъде определено, а именно точно едно отNATURAL,ONусловие на присъединяване , илиUSING(колона_присъединяване [, ...]). Вижте по-долу за значението.
За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 не изисква условие за присъединяване) и е на Атила не беше.