Ein SQL LATERAL JOIN erlaubt es einer Unterabfrage in der FROM-Klausel, auf Spalten anderer Tabellen derselben Abfrage zuzugreifen. Normale abgeleitete Tabellen sind isoliert: Sie können keine Spalten von außen sehen. Eine LATERAL-Unterabfrage dagegen wird für jede Zeile der vorangehenden Tabelle neu ausgewertet und darf deren Werte direkt referenzieren. Der SQL-Standard kennt LATERAL seit SQL:1999, verbreitet kam es aber erst mit PostgreSQL 9.3 (2013).

Syntax

SELECT t.name, sub.anzahl
FROM kunden t,
     LATERAL (SELECT COUNT(*) AS anzahl
              FROM bestellungen b
              WHERE b.kunde_id = t.id) AS sub;

Das LATERAL-Schlüsselwort steht vor der Unterabfrage in der FROM-Klausel. Die Unterabfrage darf dabei auf alle Tabellen verweisen, die vor ihr in derselben FROM-Klausel stehen. Ohne LATERAL wäre der Verweis auf t.id ein Fehler.

Top-N pro Gruppe

Der häufigste Einsatz ist die Top-N-pro-Gruppe-Abfrage: Für jede Kundin die letzten drei Bestellungen oder für jede Kategorie die teuersten Produkte. Kombiniert man LATERAL mit LIMIT, erhält man pro Zeile der äußeren Tabelle genau die gewünschte Anzahl Treffer:

SELECT k.name, p.titel
FROM kategorien k,
     LATERAL (SELECT p.titel FROM produkte p
              WHERE p.kategorie_id = k.id
              ORDER BY p.preis DESC
              LIMIT 3) AS p;

Das ist oft effizienter als Fensterfunktionen wie ROW_NUMBER(), weil nur die tatsächlich benötigten Zeilen pro Gruppe verarbeitet werden.

Unterstützung in Datenbanksystemen

  • PostgreSQL seit 9.3 (2013) – vollständiger LATERAL-Support
  • MySQL seit 8.0.14 für abgeleitete Tabellen (Lateral Derived Tables)
  • MariaDB seit 10.3 (Lateral Derived Optimization)
  • SQL Server kennt kein LATERAL-Keyword, bietet aber das Äquivalent CROSS APPLY / OUTER APPLY
  • Oracle nutzt ebenfalls CROSS APPLY / OUTER APPLY (seit 12c)

LEFT JOIN LATERAL

Liefert die Unterabfrage keine Zeile, fällt eine innere LATERAL-Verbindung weg – wie bei einem normalen JOIN. Mit LEFT JOIN LATERAL ... ON true bleibt die äußere Zeile erhalten, wenn kein Treffer existiert. Das ist praktisch für optionale Zusatzdaten.

Verwandte Grundlagen: SQL JOINs, SQL-Subquery, SQL CTE, SQL-Grundlagen sowie die zeilenweise Alternative SQL CURSOR. Transaktionssicherheit für solche Abfragen schafft SQL SAVEPOINT.