SQL INNER JOIN: Zeilen aus zwei Tabellen verbinden
Mit SQL INNER JOIN erhältst du nur die Zeilen, bei denen die Join-Bedingung in beiden Tabellen erfüllt ist. Nutze ihn, um zusammengehörige Daten zu verknüpfen, etwa wenn du Datensätze mit Nachschlagewerten verbindest und nicht passende Zeilen im Ergebnis ausgeschlossen sein sollen. Da beide Seiten das Join-Prädikat erfüllen müssen, werden Zeilen mit einem NULL-Join-Schlüssel oder ohne passende Gegenzeile automatisch herausgefiltert.
SQL INNER JOIN Beispiel zum Verknüpfen zusammengehöriger Tabellen
Ausgabe:
Die Ausgabe erscheint hier...
Ausgabe:
+-------------+-----------+
| mitarbeiter | abteilung |
+-------------+-----------+
| Alma | Technik |
| Ben | Technik |
| Cara | Vertrieb |
+-------------+-----------+
3 row(s)
So funktioniert dieses Beispiel
abteilungenenthält drei Abteilungen,mitarbeitendeenthält vier Personen mit dem Fremdschlüsselabteilung_id. Dansabteilung_idist NULL.INNER JOIN abteilungen a ON a.id = m.abteilung_idpaart jede Mitarbeitenden-Zeile mit der Abteilungs-Zeile, derenidderabteilung_identspricht. Es bleiben nur Paare erhalten, bei denen beide Seiten übereinstimmen.- Dan hat
abteilung_id = NULL. Der Operator=liefert unbekannt, wenn ein Operand NULL ist. Deshalb passt Dan zu keiner Abteilung und wird ausgeschlossen. - Die Abteilung Personal (id 3) hat keine Mitarbeitenden mit passender
abteilung_id, daher erscheint sie ebenfalls nicht. INNER JOIN entfernt nicht passende Zeilen auf beiden Seiten.
Was ist SQL INNER JOIN?
INNER JOIN bildet die Schnittmenge zweier Tabellen auf Basis eines Join-Prädikats. Logisch bleiben nur Zeilenpaare erhalten, bei denen die ON-Bedingung true ergibt. Die physische Ausführung hängt von Engine und Datenform ab (nested loops, hash join, merge join), das Ergebnis enthält aber immer nur passende Zeilen.
INNER JOIN vs LEFT JOIN
| INNER JOIN | LEFT JOIN |
|---|---|
| Gibt nur passende Zeilen aus beiden Tabellen zurück | Gibt alle Zeilen der linken Tabelle zurück, mit NULLs, wenn rechts keine Übereinstimmung existiert |
| Nicht passende Zeilen werden stillschweigend entfernt | Nicht passende linke Zeilen bleiben erhalten, rechte Spalten sind mit NULL gefüllt |
| Verwenden, wenn fehlende Treffer ungültige Daten bedeuten | Verwenden, wenn alle linken Datensätze sichtbar bleiben sollen, auch ohne Treffer |
Regel: Wähle INNER JOIN, wenn jede Ergebniszeile gültige Daten aus beiden Tabellen enthalten muss. Wechsle zu LEFT JOIN, wenn Zeilen auch ohne passenden Treffer rechts erhalten bleiben sollen.
Häufige Fehler mit SQL INNER JOIN
Fehlendes oder immer wahres Join-Prädikat
Wenn die ON-Klausel fehlt (oder eine immer wahre Bedingung verwendet wird), entsteht ein kartesisches Produkt: Jede Mitarbeitenden-Zeile wird mit jeder Abteilungs-Zeile kombiniert.
-- Falsch: kartesisches Produkt (12 Zeilen aus 4 × 3)
SELECT * FROM mitarbeitende, abteilungen;
-- Richtig: explizites Join-Prädikat
SELECT * FROM mitarbeitende m
INNER JOIN abteilungen a ON a.id = m.abteilung_id;
Nicht eindeutige Join-Schlüssel vervielfachen Zeilen
INNER JOIN liefert pro passendem Paar eine Ergebniszeile. Wenn du auf eine Tabelle mit nicht eindeutigem Schlüssel joinst, kann eine linke Zeile zu mehreren rechten Zeilen passen und dein Ergebnis vervielfachen.
INNER JOIN vs EXISTS
Verwende INNER JOIN, wenn du Spalten aus beiden Tabellen im Ergebnis brauchst. Verwende EXISTS, wenn du Zeilen nur danach filtern willst, ob eine verknüpfte Zeile vorhanden ist. EXISTS vermeidet außerdem Zeilenvervielfachung, wenn die Unterabfrage mehrere Treffer haben kann, und der Query-Planer kann oft nach dem ersten Treffer abbrechen.
-- EXISTS: eine Zeile pro Mitarbeitendem mit passender Abteilung
SELECT m.name FROM mitarbeitende m
WHERE EXISTS (SELECT 1 FROM abteilungen a WHERE a.id = m.abteilung_id);
Performance-Hinweise
Indexiere die Spalten aus dem Join-Prädikat (abteilung_id und abteilungen.id in diesem Fall). Ohne Index kann die Engine die innere Tabelle viele Male scannen. Prüfe bei großen Tabellen den Plan mit EXPLAIN QUERY PLAN und achte eher auf “USING INDEX” oder “SEARCH” als auf “SCAN”.