SQL JOIN: Tabellen sicher verknüpfen
Mit einem SQL JOIN verknüpfst du Zeilen aus mehreren Tabellen zu einer Ergebnistabelle. Die Join-Bedingung bestimmt, welche Zeilen zusammengehören; der Join-Typ bestimmt, ob auch Zeilen ohne passenden Partner erhalten bleiben.
Auf dieser Seite lernst du, Beziehungen zwischen Tabellen zu erkennen, den passenden Join-Typ auszuwählen und das Ergebnis einer Abfrage vorherzusagen.
Hake ab, was du schon kannst — und komm am Ende hierher zurück!
Welche Spalten verbinden die Tabellen?
Stell dir zwei Tabellen vor:
Mitarbeiter
| MitarbeiterID | Mitarbeitername | Bedient |
|---|---|---|
| 1 | Peter | 2 |
| 2 | Emira | 2 |
Kunde
| KundeID | Kundenname |
|---|---|
| 1 | Amir |
| 2 | Lena |
Die Spalte Mitarbeiter.Bedient verweist auf Kunde.KundeID. Deshalb lautet die passende Bedingung:
Mitarbeiter.Bedient = Kunde.KundeID
Join-Bedingung
Eine Join-Bedingung beschreibt, wann eine Zeile der einen Tabelle zu einer Zeile der anderen Tabelle passt. Häufig wird dabei ein Fremdschlüssel mit dem Primärschlüssel der anderen Tabelle verglichen.
Der Tabellenname vor dem Punkt macht eine Spalte eindeutig. Kürzere Abfragen verwenden häufig Aliasse:
FROM Mitarbeiter AS M JOIN Kunde AS K ON M.Bedient = K.KundeID
M und K sind nur Ersatznamen innerhalb dieser Abfrage. Sie verändern die Tabellen nicht.
Bestimme vor dem Schreiben der Abfrage: Welche Information suche ich, welche Tabellen enthalten sie und welche Spalten bilden die fachliche Beziehung?
INNER JOIN zeigt nur passende Paare
Ein INNER JOIN übernimmt nur Zeilenpaare, für welche die Join-Bedingung erfüllt ist. JOIN und INNER JOIN bedeuten hier dasselbe.
Gesucht sind alle Mitarbeiter zusammen mit dem Namen des Kunden, den sie bedienen.
SELECT M.Mitarbeitername, K.Kundenname FROM Mitarbeiter AS M INNER JOIN Kunde AS K ON M.Bedient = K.KundeID;
Die Abfrage arbeitet in drei gedanklichen Schritten:
FROMundINNER JOINnennen die beiden Tabellen.ONvergleichtBedientmitKundeID.SELECTlegt fest, welche Spalten im Ergebnis erscheinen.
Für Peter und Emira steht in Bedient jeweils die Zahl 2. Diese passt zu Lenas KundeID 2.
| Mitarbeitername | Kundenname |
|---|---|
| Peter | Lena |
| Emira | Lena |
Amir erscheint nicht, weil keine Mitarbeiterzeile auf seine KundeID 1 verweist.
Ein fehlender oder unbekannter Wert wird in SQL als NULL dargestellt. Bei einer normalen Gleichheitsbedingung entsteht daraus kein passendes Zeilenpaar. Ein INNER JOIN lässt die betreffende Zeile daher weg.
OUTER JOIN erhält Zeilen ohne Partner
Outer Joins ergänzen das Ergebnis eines Inner Joins um nicht passende Zeilen. Die fehlenden Werte der jeweils anderen Tabelle werden dabei NULL.
| Join-Typ | Welche Seite bleibt vollständig erhalten? |
|---|---|
LEFT JOIN | die linke Tabelle nach FROM |
RIGHT JOIN | die rechte Tabelle nach JOIN |
FULL OUTER JOIN | beide Tabellen |
OUTER kann bei LEFT, RIGHT und FULL weggelassen werden. So bedeuten LEFT JOIN und LEFT OUTER JOIN dasselbe.
LEFT JOIN
SELECT M.Mitarbeitername, K.Kundenname FROM Mitarbeiter AS M LEFT JOIN Kunde AS K ON M.Bedient = K.KundeID;
Alle Mitarbeiter bleiben erhalten. In den gegebenen Daten haben beide einen passenden Kunden. Deshalb sieht das Ergebnis genauso aus wie beim INNER JOIN:
| Mitarbeitername | Kundenname |
|---|---|
| Peter | Lena |
| Emira | Lena |
Das gleiche Ergebnis bedeutet hier nicht die gleiche Operation. Eine Mitarbeiterzeile ohne Partner würde nur beim LEFT JOIN zusätzlich erscheinen.
RIGHT JOIN
SELECT M.Mitarbeitername, K.Kundenname FROM Mitarbeiter AS M RIGHT JOIN Kunde AS K ON M.Bedient = K.KundeID;
Nun bleiben alle Kunden erhalten. Amir besitzt keinen passenden Mitarbeiter und erscheint deshalb mit NULL:
| Mitarbeitername | Kundenname |
|---|---|
| Peter | Lena |
| Emira | Lena |
NULL | Amir |
FULL OUTER JOIN
SELECT M.Mitarbeitername, K.Kundenname FROM Mitarbeiter AS M FULL OUTER JOIN Kunde AS K ON M.Bedient = K.KundeID;
Ein FULL OUTER JOIN erhält nicht passende Zeilen beider Tabellen. Mit den vorliegenden Daten entspricht sein Ergebnis dem RIGHT JOIN, weil es zwar einen Kunden ohne Mitarbeiter, aber keinen Mitarbeiter ohne Kunden gibt.
Frage nicht zuerst nach dem Namen des Join-Typs. Frage: Welche Zeilen dürfen keinesfalls verloren gehen? Daraus ergeben sich linke, rechte oder beide zu erhaltenden Seiten.
CROSS JOIN bildet alle Kombinationen
Ein CROSS JOIN kombiniert jede Zeile der ersten Tabelle mit jeder Zeile der zweiten Tabelle. Er benötigt keine ON-Bedingung.
SELECT * FROM Mitarbeiter CROSS JOIN Kunde;
Bei zwei Mitarbeiter- und zwei Kundenzeilen entstehen $2 \cdot 2 = 4$ Kombinationen:
| Mitarbeitername | Kundenname |
|---|---|
| Peter | Amir |
| Peter | Lena |
| Emira | Amir |
| Emira | Lena |
Allgemein erzeugen Tabellen mit $m$ und $n$ Zeilen genau $m \cdot n$ Kombinationen.
Ein CROSS JOIN berücksichtigt nicht die Spalte Bedient. Er eignet sich nur, wenn wirklich alle Kombinationen gebraucht werden. Bei großen Tabellen kann die Ergebnismenge sehr schnell wachsen.
ON, USING und NATURAL JOIN bewusst wählen
Für einen inneren Join kannst du die verglichenen Spalten unterschiedlich festlegen.
ON ist besonders eindeutig
ON erlaubt gleich oder unterschiedlich benannte Spalten sowie allgemeine Vergleichsbedingungen:
FROM Mitarbeiter AS M JOIN Kunde AS K ON M.Bedient = K.KundeID
Ein Join mit = heißt Equijoin. Eine allgemeine Bedingung mit einem anderen Vergleichsoperator, etwa <=, wird als Theta-Join bezeichnet.
USING nennt eine gemeinsame Spalte
Haben beide Tabellen eine gleichnamige Join-Spalte, kannst du sie ausdrücklich angeben:
FROM Mitarbeiter JOIN Kunde USING (KundeID)
Dafür müsste die Verweisspalte in Mitarbeiter ebenfalls KundeID heißen. Die gemeinsame Spalte erscheint im Ergebnis nur einmal.
NATURAL JOIN wählt automatisch
Ein NATURAL JOIN vergleicht alle gleichnamigen Spalten beider Tabellen. Im bisherigen Beispiel heißen die zusammengehörigen Spalten jedoch Bedient und KundeID. Mit diesen Spaltennamen drückt ein NATURAL JOIN die gewünschte Zuordnung deshalb nicht aus.
Würde Bedient in der Tabelle Mitarbeiter ebenfalls KundeID heißen, wäre folgende Abfrage möglich:
FROM Mitarbeiter NATURAL JOIN Kunde
Sie würde KundeID automatisch als Join-Spalte verwenden. Das kann bequem, aber riskant sein. Kommt später in beiden Tabellen eine weitere gleichnamige Spalte hinzu, wird auch sie automatisch Teil der Join-Bedingung. Die Bedeutung der Abfrage kann sich dadurch unbeabsichtigt ändern.
Verwende ON, wenn Spalten verschieden heißen oder die Bedingung ausdrücklich sichtbar sein soll. USING eignet sich für bewusst ausgewählte, gleichnamige Spalten. Bei NATURAL JOIN musst du alle gleichnamigen Spalten kennen.
Nicht jedes Datenbanksystem unterstützt NATURAL JOIN, USING oder FULL OUTER JOIN. JOIN ... ON ist deshalb oft die klarste und am breitesten einsetzbare Form.
Self Joins und mehrere Tabellen
Ein Self Join verknüpft eine Tabelle mit sich selbst. Zwei Aliasse unterscheiden die beiden Rollen derselben Tabelle.
Gegeben ist:
| PersonenID | Name | TeampartnerID |
|---|---|---|
| 1 | Peter | NULL |
| 2 | Mia | 5 |
| 3 | Andrea | 4 |
| 4 | Amir | 3 |
| 5 | Elena | 2 |
Die erste Tabellenrolle steht für die Person, die zweite für ihren Partner:
SELECT P.Name AS Person, T.Name AS Partner FROM Personen AS P INNER JOIN Personen AS T ON P.TeampartnerID = T.PersonenID;
| Person | Partner |
|---|---|
| Mia | Elena |
| Andrea | Amir |
| Amir | Andrea |
| Elena | Mia |
Peter fehlt, weil seine TeampartnerID NULL ist. Die Paare erscheinen in beiden Richtungen, weil die Ausgangstabelle beide gegenseitigen Verweise enthält.
Mehr als zwei Tabellen verknüpfen
Das Ergebnis eines Joins kann mit einer weiteren Tabelle verknüpft werden. Besitzt ein Mitarbeiter sowohl eine AdrId als auch eine AbtId, ist beispielsweise folgende Kette möglich:
FROM Mitarbeiter JOIN Adresse USING (AdrId) JOIN Abteilung USING (AbtId)
Prüfe bei jedem Schritt getrennt, welche Spalten verbunden werden und welche Zeilen erhalten bleiben. Das ist besonders wichtig bei Outer Joins: Ihre Reihenfolge und Richtung können die Ergebnismenge verändern.
Karteikasten
Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.
Alles auf einen Blick
- SQL JOIN
- Beziehung bestimmen
- Primär- und Fremdschlüssel erkennen
- Join-Bedingung mit `ON` formulieren
- Ergebnismenge wählen
- INNER: nur passende Paare
- LEFT oder RIGHT: eine Seite vollständig
- FULL: beide Seiten vollständig
- CROSS: alle Kombinationen
- Syntax bewusst einsetzen
- `ON` für ausdrückliche Bedingungen
- `USING` für ausgewählte gleichnamige Spalten
- NATURAL für alle gleichnamigen Spalten
- Besondere Anwendungen
- Self Join mit zwei Aliasnamen
- mehrere Joins schrittweise prüfen
- Beziehung bestimmen
Abschluss-Check
Du kannst eine Join-Abfrage prüfen, indem du vier Fragen beantwortest: Welche Tabellen brauche ich? Welche Spalten bilden die Beziehung? Welche Zeilen müssen erhalten bleiben? Welche Zeilen und NULL-Ergänzungen erwarte ich im Ergebnis?
Mit Google fortfahren