sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvad er forskellen mellem LATERAL JOIN og en underforespørgsel i PostgreSQL?

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 (CROSS JOIN kræver ikke en deltagelsesbetingelse) og Attilas er var ikke.



  1. En oversigt over genererede kolonner til PostgreSQL

  2. MySQL Basic Database Administration Commands – Del I

  3. Sådan ændrer du størrelsen på formularkontrolelementer i Access 2016

  4. Opretter forbindelse til 4D fra Java