Sobald du über einfache Abfragen einer einzelnen Tabelle hinausgehst, brauchst du Joins. Sie sind das Herzstück relationaler Datenbanken und gleichzeitig das Thema, an dem die meisten Einsteiger hängen bleiben. Dabei ist die Idee dahinter einfach: Joins verbinden Daten aus mehreren Tabellen anhand gemeinsamer Werte. Wenn du die vier Grundtypen einmal verstanden hast, eröffnen sich dir völlig neue Möglichkeiten der Datenauswertung. Dieser Artikel macht Joins endlich greifbar.
Warum überhaupt mehrere Tabellen?
In gut entworfenen Datenbanken werden Daten auf mehrere Tabellen verteilt, statt alles in einer riesigen Tabelle zu stapeln. Das nennt man Normalisierung. Ein Beispiel: Statt zu jeder Bestellung den kompletten Kundennamen, die Adresse und die Telefonnummer zu wiederholen, speicherst du den Kunden einmal in einer kunden-Tabelle und verweist von der bestellungen-Tabelle nur über eine kunden_id darauf.
Das spart Speicher, verhindert Inkonsistenzen (eine Adressänderung muss nur an einer Stelle erfolgen) und hält die Daten sauber. Der Preis: Um zusammengehörende Informationen anzuzeigen, musst du die Tabellen beim Abfragen wieder zusammenführen – und genau das leisten Joins.
Primär- und Fremdschlüssel: Die Verbindungspunkte
Joins funktionieren über Schlüssel:
- Der Primärschlüssel (Primary Key) identifiziert jede Zeile einer Tabelle eindeutig – etwa die
idin derkunden-Tabelle. - Der Fremdschlüssel (Foreign Key) ist eine Spalte in einer anderen Tabelle, die auf diesen Primärschlüssel verweist – etwa
kunden_idin derbestellungen-Tabelle.
Diese Schlüssel sind die Brücken, über die Joins zwei Tabellen verbinden. Für unsere Beispiele nutzen wir zwei Tabellen: kunden (mit id, name) und bestellungen (mit id, kunden_id, betrag).
INNER JOIN: Die Schnittmenge
Der INNER JOIN ist der am häufigsten genutzte Join. Er liefert nur Zeilen, für die es in beiden Tabellen eine Übereinstimmung gibt:
SELECT kunden.name, bestellungen.betrag FROM kunden INNER JOIN bestellungen ON kunden.id = bestellungen.kunden_id;
Diese Abfrage gibt jeden Kunden zusammen mit jeder seiner Bestellungen aus. Der entscheidende Teil ist die ON-Bedingung: Sie sagt der Datenbank, welche Spalten zusammenpassen müssen (hier: kunden.id entspricht bestellungen.kunden_id).
Wichtig: Kunden ohne Bestellung tauchen im Ergebnis nicht auf – ebenso wenig wie Bestellungen ohne gültigen Kunden. Der INNER JOIN zeigt nur die Schnittmenge. Genau das willst du oft, manchmal aber eben nicht – und dann brauchst du einen Outer Join.
LEFT JOIN: Alles aus der linken Tabelle
Der LEFT JOIN (vollständig: LEFT OUTER JOIN) gibt alle Zeilen der linken Tabelle zurück – auch dann, wenn es in der rechten keine Übereinstimmung gibt:
SELECT kunden.name, bestellungen.betrag FROM kunden LEFT JOIN bestellungen ON kunden.id = bestellungen.kunden_id;
Jetzt erscheinen alle Kunden im Ergebnis – auch jene, die noch nie etwas bestellt haben. Für diese Kunden steht in der Spalte betrag der Wert NULL (also "kein Wert vorhanden").
Das macht den LEFT JOIN extrem nützlich, um genau diese "Lücken" zu finden. Die klassische Frage "Welche Kunden haben noch nie bestellt?" beantwortest du so:
SELECT kunden.name FROM kunden LEFT JOIN bestellungen ON kunden.id = bestellungen.kunden_id WHERE bestellungen.id IS NULL;
Du joinst alle Kunden mit ihren Bestellungen und filterst dann auf jene, bei denen keine Bestellung existiert (IS NULL). Diese Technik – Anti-Join genannt – ist in der Praxis Gold wert.
RIGHT JOIN: Alles aus der rechten Tabelle
Der RIGHT JOIN ist das Spiegelbild des LEFT JOIN: Er gibt alle Zeilen der rechten Tabelle zurück, auch ohne Treffer links. In der Praxis wird er selten verwendet, weil man dasselbe Ergebnis erreicht, indem man die Tabellen umstellt und einen LEFT JOIN nimmt. Viele Teams verbieten RIGHT JOINs sogar bewusst aus Lesbarkeitsgründen – ein LEFT JOIN liest sich für die meisten Menschen natürlicher, weil man die "Haupttabelle" zuerst nennt.
FULL JOIN: Beide Seiten vollständig
Der FULL JOIN (FULL OUTER JOIN) kombiniert LEFT und RIGHT: Er gibt alle Zeilen aus beiden Tabellen zurück. Wo es keine Übereinstimmung gibt, werden die fehlenden Spalten mit NULL gefüllt – egal auf welcher Seite. Das ist nützlich, um Unterschiede zwischen zwei Datensätzen aufzuspüren, etwa beim Abgleich zweier Importe.
Ein Hinweis: Nicht alle Datenbanken unterstützen FULL JOIN direkt. MySQL etwa kennt ihn nicht nativ – dort baust du ihn aus einem LEFT JOIN und einem RIGHT JOIN mit UNION nach. PostgreSQL und SQLite (neuere Versionen) beherrschen FULL JOIN dagegen direkt.
Die Venn-Diagramm-Eselsbrücke
Viele merken sich die Join-Typen über Mengen-Bilder. Stell dir zwei überlappende Kreise vor (linke und rechte Tabelle):
- INNER JOIN: nur der überlappende Bereich in der Mitte.
- LEFT JOIN: der gesamte linke Kreis (inklusive Überlappung).
- RIGHT JOIN: der gesamte rechte Kreis (inklusive Überlappung).
- FULL JOIN: beide Kreise vollständig.
Diese Eselsbrücke hat eine kleine Schwäche – sie ignoriert, dass ein Kunde mehrere Bestellungen haben kann und Zeilen sich dadurch vervielfachen. Für den Einstieg ist sie aber eine hervorragende Gedächtnisstütze.
Aliase machen Joins lesbar
Lange Tabellennamen vor jeder Spalte zu wiederholen, bläht Abfragen auf. Deshalb vergibt man Tabellen-Aliase:
SELECT k.name, b.betrag FROM kunden AS k INNER JOIN bestellungen AS b ON k.id = b.kunden_id;
Mit k und b als Kürzeln wird die Abfrage deutlich kompakter und lesbarer – besonders, wenn du drei, vier oder mehr Tabellen joinst. Das ist gängige Praxis und gehört zum guten Stil.
Mehrere Tabellen joinen
Du bist nicht auf zwei Tabellen beschränkt. Joins lassen sich verketten. Angenommen, jede Bestellung enthält mehrere Produkte über eine Zwischentabelle bestellpositionen:
SELECT k.name, p.bezeichnung, bp.menge FROM kunden AS k INNER JOIN bestellungen AS b ON k.id = b.kunden_id INNER JOIN bestellpositionen AS bp ON b.id = bp.bestellung_id INNER JOIN produkte AS p ON bp.produkt_id = p.id;
Die Datenbank arbeitet sich Schritt für Schritt durch die Verknüpfungen. So baust du komplexe Auswertungen über das ganze Datenmodell hinweg – vom Kunden über die Bestellung bis zum einzelnen Produkt.
Häufige Stolperfallen
- Fehlende ON-Bedingung: Vergisst du das
ON(oder schreibst eine falsche Bedingung), entsteht ein kartesisches Produkt – jede Zeile links wird mit jeder Zeile rechts kombiniert. Bei großen Tabellen explodiert die Ergebnismenge. - WHERE statt ON beim LEFT JOIN: Eine Bedingung auf die rechte Tabelle im WHERE-Teil kann einen LEFT JOIN heimlich in einen INNER JOIN verwandeln, weil NULL-Zeilen herausgefiltert werden. Filter, die nur die rechte Tabelle betreffen, gehören in die ON-Klausel.
- Mehrdeutige Spaltennamen: Heißt eine Spalte in beiden Tabellen gleich (z. B.
id), musst du sie mit Tabellenname oder Alias qualifizieren, sonst gibt es einen Fehler. - Performance: Joins über nicht indizierte Fremdschlüssel sind langsam. Mehr dazu in unserem Artikel zu Datenbank-Indizes.
Joins üben und vertiefen
Joins versteht man am besten durch Ausprobieren. Lege dir zwei kleine Tabellen mit ein paar Zeilen an und führe dieselbe Abfrage einmal als INNER und einmal als LEFT JOIN aus – der Unterschied wird sofort sichtbar. Wenn du die Grundbefehle noch festigen willst, lies zuerst unseren Einstieg in die SQL-Grundlagen. Und für die Arbeit mit Datenformaten rund um deine Datenbank findest du im Webtools-Bereich von kotsch.tech praktische Konverter und Helfer.
Häufige Fragen
Was ist der Unterschied zwischen JOIN und INNER JOIN?
Es gibt keinen. Schreibst du nur JOIN, interpretieren alle gängigen Datenbanken das als INNER JOIN. Beide sind identisch – die ausführliche Schreibweise macht die Absicht nur klarer.
Wann nehme ich LEFT JOIN, wann INNER JOIN?
INNER JOIN, wenn du nur Datensätze mit Treffer in beiden Tabellen brauchst. LEFT JOIN, wenn du alle Zeilen der ersten Tabelle behalten willst – auch ohne passende Gegenstücke, etwa um fehlende Verknüpfungen aufzuspüren.
Warum bekomme ich mehr Zeilen, als ich erwartet habe?
Wenn ein Datensatz links mehrere passende Datensätze rechts hat, wird er für jede Übereinstimmung wiederholt. Ein Kunde mit fünf Bestellungen erscheint fünfmal. Das ist korrektes Verhalten – mit GROUP BY und Aggregatfunktionen kannst du die Ergebnisse wieder zusammenfassen.
Sind Joins langsam?
Nicht grundsätzlich. Auf indizierten Schlüsseln sind Joins sehr effizient. Langsam werden sie vor allem, wenn die Join-Spalten nicht indiziert sind oder versehentlich ein kartesisches Produkt entsteht. Ein passender Index auf dem Fremdschlüssel ist der wichtigste Hebel.