PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Каква е разликата между LATERAL JOIN и подзаявка в PostgreSQL?

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да добавите автоматично увеличаващ се първичен ключ към съществуваща таблица в PostgreSQL?

  2. Как да автоматизирате PostgreSQL 12 репликация и отказ с repmgr – част 2

  3. Как да внедрите високодостъпен Canvas LMS с клъстер от база данни PostgreSQL

  4. Как да сортирате резултата от string_agg()

  5. PDO срещу pg_* функции