Hvad er en LATERAL
deltage?
Funktionen blev introduceret med PostgreSQL 9.3. Manualen:
Underforespørgsler, der vises i FROM
kan indledes med nøgleordetLATERAL
. Dette giver dem mulighed for at referere til kolonner, der er angivet ved at gå foran FROM
genstande. (Uden LATERAL
, hver underforespørgsel evalueres uafhængigt og kan derfor ikke krydsreference nogen anden FRA
vare.)
Tabelfunktioner, der vises i FROM
kan også indledes med nøgleordet LATERAL
, men for funktioner er nøgleordet valgfrit; Funktionens argumenter kan indeholde referencer til kolonner, der er angivet foran FROM
varer under alle omstændigheder.
Der er givet grundlæggende kodeeksempler.
Mere som en korreleret underforespørgsel
En LATERAL
join er mere som en korreleret underforespørgsel, ikke en almindelig underforespørgsel, idet udtryk til højre for en LATERAL
join evalueres én gang for hver række tilbage af det - ligesom en korreleret underforespørgsel - mens en almindelig underforespørgsel (tabeludtryk) evalueres en gang kun. (Forespørgselsplanlæggeren har dog måder at optimere ydeevnen for begge.)
Relateret svar med kodeeksempler for begge side om side, hvilket løser det samme problem:
- Optimer GROUP BY-forespørgsel for at hente seneste række pr. bruger
Til returnering af mere end én kolonne , en LATERAL
join er typisk enklere, renere og hurtigere.
Husk også, at det, der svarer til en korreleret underforespørgsel, er LEFT JOIN LATERAL ... ON true
:
- Kald en sæt-returnerende funktion med et array-argument flere gange
Ting, en underforespørgsel ikke kan
Der er ting, der er en LATERAL
join kan gøre, men en (korreleret) underforespørgsel kan ikke (let). En korreleret underforespørgsel kan kun returnere en enkelt værdi, ikke flere kolonner og ikke flere rækker - med undtagelse af bare funktionskald (som multiplicerer resultatrækker, hvis de returnerer flere rækker). Men selv visse sæt-returnerende funktioner er kun tilladt i FROM
klausul. Ligesom unnest()
med flere parametre i Postgres 9.4 eller nyere. Manualen:
Dette er kun tilladt i FROM
klausul;
Så dette virker, men kan ikke (let) erstattes med en underforespørgsel:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
Kommaet (,
) i FROM
klausul er kort notation for CROSS JOIN
.LATERAL
antages automatisk for tabelfunktioner.
Om specialtilfældet UNNEST( array_expression [, ... ] )
:
- Hvordan erklærer du, at en sæt-retur-funktion kun er tilladt i FROM-sætningen?
Indstil returnerende funktioner i SELECT
liste
Du kan også bruge sæt-returnerende funktioner som unnest()
i SELECT
liste direkte. Dette plejede at udvise overraskende adfærd med mere end én sådan funktion i samme SELECT
liste op til Postgres 9.6. Men det er endelig blevet renset med Postgres 10 og er et gyldigt alternativ nu (selvom ikke standard SQL). Se:
- Hvad er den forventede adfærd for flere sæt-returnerende funktioner i SELECT-sætning?
Ud fra ovenstående eksempel:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Sammenligning:
dbfiddle for side 9.6 her
dbfiddle til s. 10 her
Afklar misinformation
Manualen:
Til INNER
og YDRE
jointyper, skal en join-betingelse specificeres, nemlig præcis én af NATURAL
, TIL
join_condition eller USING
(deltag_kolonne [, ...]). Se betydningen nedenfor.
For CROSS JOIN
, ingen af disse klausuler kan forekomme.
Så disse to forespørgsler er gyldige (selvom de ikke er særligt nyttige):
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;
Selvom denne ikke er:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Det er derfor, at Andomars kodeeksempel er korrekt (er var ikke.