Какво е 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
не изисква условие за присъединяване) и е на Атила не беше.