Eher wie eine korrelierte Unterabfrage
Ein LATERAL
Join (Postgres 9.3 oder höher) ähnelt eher einer korrelierten Unterabfrage , nicht einer einfachen Unterabfrage. Wie Andomar betonte, muss eine Funktion oder Unterabfrage rechts von einem LATERAL
Join - genau wie eine korrelierte Unterabfrage - für jede Zeile links davon einmal ausgewertet werden, während eine einfache Unterabfrage (Tabellenausdruck) nur einmal ausgewertet wird . (Der Abfrageplaner bietet jedoch Möglichkeiten, die Leistung für beide zu optimieren.)
Diese verwandte Antwort enthält Codebeispiele für beide nebeneinander, mit denen das gleiche Problem gelöst wird:
Wenn Sie mehr als eine Spalte zurückgeben , ist ein LATERAL
Join normalerweise einfacher, sauberer und schneller.
Denken Sie auch daran, dass das Äquivalent einer korrelierten Unterabfrage lautet LEFT JOIN LATERAL ... ON true
:
Lesen Sie das Handbuch weiter LATERAL
Es ist maßgeblicher als alles, was wir hier beantworten werden:
Dinge, die eine Unterabfrage nicht kann
Es gibt Dinge, die ein LATERAL
Join tun kann, aber eine (korrelierte) Unterabfrage kann nicht (leicht). Eine korrelierte Unterabfrage kann nur einen einzelnen Wert zurückgeben, nicht mehrere Spalten und nicht mehrere Zeilen - mit Ausnahme von bloßen Funktionsaufrufen (die Ergebniszeilen multiplizieren, wenn sie mehrere Zeilen zurückgeben). Aber auch bestimmte Set-Return-Funktionen sind nur in der FROM
Klausel zulässig . Wie unnest()
bei mehreren Parametern in Postgres 9.4 oder höher. Das Handbuch:
Dies ist nur in der FROM
Klausel erlaubt ;
Das funktioniert also, kann aber nicht einfach durch eine Unterabfrage ersetzt werden:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
Das Komma ( ,
) in der FROM
Klausel ist eine Kurzschreibweise für CROSS JOIN
.
LATERAL
wird für Tabellenfunktionen automatisch angenommen.
Mehr zum Sonderfall von UNNEST( array_expression [, ... ] )
:
Set-Return-Funktionen in der SELECT
Liste
Sie können auch Set-Return-Funktionen wie unnest()
in der SELECT
Liste direkt verwenden. Dies zeigte ein überraschendes Verhalten mit mehr als einer solchen Funktion in derselben SELECT
Liste bis zu Postgres 9.6. Aber es wurde endlich mit Postgres 10 bereinigt und ist jetzt eine gültige Alternative (auch wenn es sich nicht um Standard-SQL handelt). Sehen:
Aufbauend auf dem obigen Beispiel:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Vergleich:
dbfiddle für pg 9.6 hier
dbfiddle für pg 10 hier
Klären Sie Fehlinformationen
Das Handbuch:
Für die INNER
und OUTER
Join - Typen, ein Join - Bedingung angegeben werden muss, und zwar genau einen NATURAL
, ON
join_bedingung oder USING
( join_column [, ...]). Siehe unten für die Bedeutung.
Denn CROSS JOIN
keine dieser Klauseln kann erscheinen.
Diese beiden Abfragen sind also gültig (auch wenn sie nicht besonders nützlich sind):
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;
Während dieser nicht ist:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Aus diesem Grund ist das Codebeispiel von @ Andomar korrekt (für das CROSS JOIN
keine Join-Bedingung erforderlich ist) und das von @ Attila ist ungültig.
apply
ist die gleiche wie dielateral
von dem SQL - Standard)