SQL JOIN Kompendium
SQL Anfänger sollten sich nicht durch die vielen SQL JOIN Varianten verwirren lassen, es gibt nur 2 wirklich relevante Arten von Joins:
Den INNER JOIN und den LEFT JOIN.
Alle anderen existierenden Join-Varianten lassen sich gegen die beiden o.g. Joins austauschen oder aber deren Einsatz macht nur in Ausnahmefällen Sinn.
Leider sind diese beiden Begriffe nicht komplementär. Es wäre wohl glücklicher gewesen,
- den INNER JOIN und
- statt dem LEFT JOIN den synonymen OUTER JOIN
zu verwenden, aber die Branche hat sich nun einmal für den LEFT JOIN entschieden.
Syntax und Notation von SQL-Statements mit Joins
SQL-Statements sind leider oft das Stiefkind bei der Notation bzw. dem Layout von Quellcode.
Beim Programmcode achtet man zur besseren Lesbarkeit penibel auf die Aufteilung in viele Zeilen und deren Einrückung, SQL-Statements werden dagegen meist ohne Zeilenumbrüche niedergeschrieben. Außerdem kommen oft nicht empfehlenswerte oder zu missbilligende JOIN-Typen oder -Benennungen zum Einsatz und die Verknüpfung der Tabellen wird mal in einer, mal in einer äquivalenten anderen Syntax bewerkstelligt.
Da SQL-Statements aber elementare Zusammenhänge ausdrücken, empfiehlt es sich, deren Notation genausoviel Beachtung zu schenken, wie der vom Programmcode.
Die u.g. bevorzugten syntaktische Varianten in den Beispiel SQL-Statements mögen als Vorschlag für eine gute Notation dienen.
Relevante JOIN Arten
INNER JOIN
Mengentheoretisch gesehen die Schnittmenge aus Tabelle 1 und 2 hinsichtlich der Werte der verknüpften Felder. D.h.
das Abfrageergebnis enthält NUR Datensätze aus Tabelle 1 und 2, bei denen die Werte der verknüpften Felder gleich sind.
Es kann also zum Verlust von Datensätzen aus Tabelle 1 kommen,
wenn es keine Datensätze aus Tabelle 2 mit entsprechendem Wert aus Tabelle 1 für das verknüpfte Feld gibt.
Beispiel SQL-Statements
Die vom Wizard of LEFT JOIN bevorzugte syntaktische Variante
SELECT
p.*,
l.*
FROM
Produkte p
INNER JOIN Lieferanten l
ON p.LieferantenId = l.Id
ist äquivalent zu
SELECT
p.*,
l.*
FROM
Produkte p
INNER JOIN Lieferanten l
WHERE
p.LieferantenId = l.Id
und ebenfalls äquivalent zu
SELECT
p.*,
l.*
FROM
Produkte p,
Lieferanten l
WHERE
p.LieferantenId = l.Id
LEFT JOIN
Mengentheoretisch gesehen die Vereinigungsmenge aus Tabelle 1 und 2 hinsichtlich der Werte der verknüpften Felder. D.h.
das Abfrageergebnis enthält ALLE Datensätze aus Tabelle 1 und aus Tabelle 2 nur solche, für die es passende Werte des verknüpften Feldes gibt.
Die evtl. fehlenden Daten aus Tabelle 2 werden im Abfrageergebnis mit sog. NULL-Werten aufgefüllt.
Beispiel SQL-Statements
Produkte ohne LieferantenId oder solche mit LieferantenId, zu der es keinen korrespondierenden Lieferanten-Datensatz gibt, werden von den o.g. Statements mit INNER JOIN nicht zurückgeliefert. Produkte sowohl mit als auch ohne korrespondierende Lieferanten-Datensätze bekommt man - ggfs. mit NULL-Werten in den l.* Feldern - per LEFT JOIN.
Die vom Wizard of LEFT JOIN bevorzugte syntaktische Variante
SELECT
p.*,
l.*
FROM
Produkte p
LEFT JOIN Lieferanten l
ON p.LieferantenId = l.Id
ist äquivalent zu
SELECT
p.*,
l.*
FROM
Produkte p
LEFT JOIN Lieferanten l
WHERE
p.LieferantenId = l.Id
Bei Oracle gibt es noch eine äquivalente Variante, die nur verwendet werden sollte, wenn man weiß, daß die Applikation niemals auf eine andere Datenbank portiert werden wird.
SELECT
p.*,
l.*
FROM
Produkte p,
Lieferanten l
WHERE
p.LieferantenId = l.Id (+)
Missbilligte und exotische JOIN Arten
JOIN
Ein Synonym für INNER JOIN.
Die Verwendung ist nicht empfehlenswert, denn für diesen Verknüpfungstyp hat sich in der Branche der INNER JOIN etabliert.
OUTER JOIN oder LEFT OUTER JOIN
Synonyme für LEFT JOIN.
Die Verwendung ist nicht empfehlenswert, denn für diesen Verknüpfungstyp hat sich in der Branche der LEFT JOIN etabliert.
RIGHT JOIN
Lässt sich stets durch Vertauschen der Reihenfolge der Nennung der Tabellen in einen LEFT JOIN umformen.
Die Verwendung ist nicht empfehlenswert, denn für diesen Verknüpfungstyp hat sich in der Branche der LEFT JOIN etabliert.
FULL JOIN oder FULL OUTER JOIN
Kombiniert die Eigenschaften eines LEFT JOIN und RIGHT JOIN, d.h. alle Datensätze sowohl aus Tabelle 1 als auch aus Tabelle 2
sind im Abfrageergebnis enthalten. Fehlenden Daten aus Tabelle 1 und 2 werden im Abfrageergebnis mit sog. NULL-Werten aufgefüllt.
Dieser Verknüpfungstyp kommt äußerst selten zum Einsatz und wird auch nicht von allen Datenbanken unterstützt.
CROSS JOIN
Ist bei MySQL ein Synonym für INNER JOIN.
Die Nutzung ist bei MySQL nicht empfehlenswert, denn für diesen Verknüpfungstyp hat sich in der Branche der INNER JOIN etabliert.
Bei anderen Datenbanken handelt es sich dagegen um das kartesische Produkt aus den verknüpften Tabellen, d.h. jeder Datensatz aus Tabelle 1 wird mit jedem Datensatz aus Tabelle 2 kombiniert
(Anm.: Bei MySQL erhält man das kartesische Produkt mittels eines INNER JOIN ohne die Tabellen dabei zu verknüpfen).
Ein kartesisches Produkt von Tabellen macht nur in Ausnahmefällen Sinn. Normalerweise möchte man im Abfrageergebnis die Anzahl der Datensätze begrenzen und nicht ausufern lassen.
NATURAL JOIN oder NATURAL LEFT JOIN bzw. NATURAL OUTER JOIN
Diese haben sämtliche Eigenschaften eines INNER JOIN bzw. LEFT JOIN, aber die verknüpften Felder werden nicht explizit angegeben,
sondern die Verknüpfung erfolgt allein über Tabellen-übergreifende Gleichheit von Feld-Namen.
Von der Verwendung ist abzuraten, denn man handelt sich damit unnötigerweise eine mögliche Fehlerquelle ein.
Stattdessen sollte ein INNER JOIN bzw. LEFT JOIN unter expliziter Angabe der verknüpften Felder verwendet werden.
STRAIGHT_JOIN
Hat alle Eigenschaften eines INNER JOIN.
Darüber hinaus wird erzwungen, daß bei der Abarbeitung der Anfrage die linke Tabelle zuerst eingelesen wird.
Das ist aber normalerweise sowieso der Fall, sodaß der STRAIGHT_JOIN nur selten für Optimierungs-Versuche zum Einsatz kommt.