Informatik

SQL JOIN: Tabellen sicher verknüpfen

SQL JOIN: Tabellen sicher verknüpfen

SQL JOIN: Tabellen sicher verknüpfen
SQL JOIN: Tabellen sicher verknüpfen
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

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.

Deine Lernziele

Hake ab, was du schon kannst — und komm am Ende hierher zurück!

Welche Spalten verbinden die Tabellen?

Eine Tabelle enthält Zeilen für einzelne Datensätze und Spalten für deren Eigenschaften. SQL ist eine Sprache, mit der du solche Daten abfragen kannst. Betrachte diese zwei fiktiven Beispieltabellen:

Mitarbeiter

MitarbeiterIDMitarbeiternameBedient
1Peter2
2Emira2

Kunde

KundeIDKundenname
1Amir
2Lena

Ein Primärschlüssel kennzeichnet jede Zeile eindeutig und enthält keine NULL-Werte, also keine fehlenden Werte. Hier übernehmen MitarbeiterID und KundeID diese Rolle. Ein Fremdschlüssel verweist auf einen Schlüssel der zugehörigen Tabelle; in diesem Beispiel ist das Bedient.

Die Spalte Mitarbeiter.Bedient verweist auf Kunde.KundeID. Deshalb lautet die passende Bedingung:

Mitarbeiter.Bedient = Kunde.KundeID

Definition

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. Ein Ausschnitt, der mit FROM beginnt, ist noch keine vollständige Abfrage: Davor gehört eine SELECT-Liste, die die auszugebenden Spalten nennt.

Die folgenden Ergebnistabellen zeigen die enthaltenen Zeilen. Ihre Reihenfolge ist ohne eine ausdrückliche Sortierung mit ORDER BY nicht garantiert.

Merke

Bestimme vor dem Schreiben der Abfrage: Welche Information suche ich, welche Tabellen enthalten sie und welche Spalten bilden die fachliche Beziehung?

Teste dich
Frage 1 von 1LeichtWelche Bedingung ordnet im Beispiel jedem Mitarbeiter den bedienten Kunden zu?
Lösung: Mitarbeiter.Bedient = Kunde.KundeID — Bedient enthält die ID des zugeordneten Kunden und wird deshalb mit KundeID verglichen.
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.

Beispiel

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:

  1. FROM und INNER JOIN nennen die beiden Tabellen.
  2. ON vergleicht Bedient mit KundeID.
  3. SELECT legt fest, welche Spalten im Ergebnis erscheinen.

Für Peter und Emira steht in Bedient jeweils die Zahl 2. Diese passt zu Lenas KundeID 2.

MitarbeiternameKundenname
PeterLena
EmiraLena

Amir erscheint nicht, weil keine Mitarbeiterzeile auf seine KundeID 1 verweist.

SQL kennzeichnet fehlende oder unbekannte Werte mit NULL. Enthält einer der beiden verglichenen Werte NULL, ergibt ein normaler Vergleich mit = den Wahrheitswert „unbekannt“. Auch NULL = NULL ist nicht wahr. Für einen Treffer muss die Join-Bedingung aber wahr sein; in unserem Gleichheitsjoin entsteht deshalb kein passendes Paar.

Eine Zeile kann mehrere passende Partner haben. Deshalb erscheint Lena hier zweimal: einmal mit Peter und einmal mit Emira. Ein Join liefert eine Ergebniszeile pro passendem Paar.

Teste dich
Frage 1 von 1MittelWas geschieht bei einem INNER JOIN mit einem Kunden, zu dem keine Mitarbeiterzeile passt?
Lösung: Er erscheint nicht im Ergebnis. — Ein INNER JOIN enthält ausschließlich Zeilenpaare, welche die Join-Bedingung erfüllen.
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. Diese Erhaltung gilt für das Join-Ergebnis; eine zusätzliche WHERE-Bedingung kann danach wieder Zeilen herausfiltern.

Join-TypWelche Seite bleibt vollständig erhalten?
LEFT JOINdie linke Tabelle nach FROM
RIGHT JOINdie rechte Tabelle nach JOIN
FULL OUTER JOINbeide 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:

MitarbeiternameKundenname
PeterLena
EmiraLena

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:

MitarbeiternameKundenname
PeterLena
EmiraLena
NULLAmir

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.

Übung: Eine Mitarbeiterin ohne Kunden

Ergänze nur für diese Übung die Mitarbeiterzeile (3, Lina, NULL). Die Kundentabelle bleibt unverändert. Welche Zeilen liefern die obigen LEFT- und FULL-JOIN-Abfragen jetzt? Überlege zuerst selbst.

Lösung: Peter und Emira passen weiterhin zu Lena. Für Lina liefert NULL = KundeID keinen Treffer. Der LEFT JOIN erhält Lina dennoch und ergänzt ihre Kundenspalte mit NULL:

MitarbeiternameKundenname
PeterLena
EmiraLena
LinaNULL

Der FULL OUTER JOIN enthält zusätzlich die Zeile NULL | Amir, weil er auch den Kunden ohne Mitarbeiter erhält. In den folgenden Abschnitten gelten wieder die ursprünglichen zwei Mitarbeiterzeilen.

Merke

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.

Teste dich
Frage 1 von 2MittelDu brauchst eine Liste aller Kunden, auch wenn sie noch von niemandem bedient werden. Kunde steht rechts vom Join. Welcher Typ passt?
Lösung: RIGHT JOIN — Da Kunde rechts steht und vollständig erhalten bleiben soll, passt ein RIGHT JOIN. Durch Vertauschen der Tabellen könntest du dieselbe Absicht auch mit einem LEFT JOIN ausdrücken.
Frage 2 von 2SchwerZwei Join-Abfragen liefern bei den aktuellen Daten dieselben Zeilen. Was folgt daraus?
Lösung: Die Join-Typen können trotzdem unterschiedliche Regeln für andere Daten besitzen. — Ob zusätzliche Zeilen entstehen, hängt davon ab, ob die zu erhaltende Seite tatsächlich Zeilen ohne Partner enthält.
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 M.Mitarbeitername, K.Kundenname FROM Mitarbeiter AS M CROSS JOIN Kunde AS K;

Bei zwei Mitarbeiter- und zwei Kundenzeilen entstehen $2 \cdot 2 = 4$ Kombinationen:

MitarbeiternameKundenname
PeterAmir
PeterLena
EmiraAmir
EmiraLena

Allgemein erzeugen Tabellen mit $m$ und $n$ Zeilen genau $m \cdot n$ Kombinationen.

Gut zu wissen

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.

Teste dich
Frage 1 von 1MittelTabelle A hat 4 Zeilen, Tabelle B hat 3 Zeilen. Wie viele Zeilen erzeugt ihr CROSS JOIN?
Lösung: 12 — Jede der 4 Zeilen wird mit jeder der 3 Zeilen kombiniert: $4 \cdot 3 = 12$.
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, dessen Bedingung nur Gleichheitsvergleiche verwendet, heißt Equijoin. Der allgemeinere Theta-Join erlaubt auch andere Vergleichsbedingungen, etwa <=. Ein Equijoin ist damit ein Spezialfall eines Theta-Joins.

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. Bei SELECT *, also der Ausgabe aller Spalten, erscheint die gemeinsame Join-Spalte 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. Weil diese beiden Tabellen gar keine gleichnamigen Spalten haben, verhält er sich hier sogar wie ein CROSS JOIN.

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.

Merke

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.

Die gezeigten Join-Formen sind beispielsweise in PostgreSQL möglich. Andere Datenbanksysteme unterstützen nicht jede Form: SQL Server bietet weder NATURAL JOIN noch JOIN ... USING; MySQL 8.4 bietet keinen FULL OUTER JOIN. Eine ausdrückliche ON-Bedingung ist oft gut übertragbar, ersetzt aber keinen fehlenden Join-Typ.

Teste dich
Frage 1 von 1SchwerBeide Tabellen erhalten später zusätzlich eine Spalte Ort, die jeweils etwas anderes bedeutet. Welche Abfrage bleibt auf die beabsichtigte ID-Verknüpfung begrenzt?
Lösung: JOIN ... ON A.KundeID = B.KundeID — Eine ausdrücklich formulierte ON-Bedingung ändert sich nicht nur deshalb, weil weitere gleichnamige Spalten hinzukommen.
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 die fiktive Tabelle Personen:

PersonenIDNameTeampartnerID
1PeterNULL
2Mia5
3Andrea4
4Amir3
5Elena2

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;

PersonPartner
MiaElena
AndreaAmir
AmirAndrea
ElenaMia

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. Für ein weiteres fiktives Beispiel hat Mitarbeiter die Spalten MitarbeiterID, Mitarbeitername, AdrId und AbtId. Dazu kommen Adresse(AdrId, Strasse) und Abteilung(AbtId, Abteilungsname). AdrId verweist auf die Adresse, AbtId auf die Abteilung. Dann ist folgende Kette möglich:

FROM Mitarbeiter JOIN Adresse USING (AdrId) JOIN Abteilung USING (AbtId)

Der erste Join ordnet über AdrId die Adresse zu. Der zweite ergänzt über AbtId den Abteilungsnamen. Weil beide Joins innere Joins sind, bleiben nur Mitarbeiter mit passender Adresse und passender Abteilung übrig.

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.

Teste dich
Frage 1 von 1MittelWozu dienen die zwei Aliasse im gezeigten Self Join?
Lösung: Damit dieselbe Tabelle in zwei unterscheidbaren Rollen verwendet werden kann. — Die Aliasse erlauben Ausdrücke wie P.TeampartnerID = T.PersonenID, obwohl beide Spalten aus derselben Tabelle stammen.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • 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
Abschluss-Check
Teste dich
Frage 1 von 4LeichtWelcher Join enthält ausschließlich Zeilenpaare, welche die Join-Bedingung erfüllen?
Lösung: INNER JOIN — Ein INNER JOIN entfernt jede Kombination, welche die Bedingung nicht erfüllt.
Frage 2 von 4MittelAlle Mitarbeiter sollen erscheinen, auch wenn Bedient keinen passenden Kunden bezeichnet. Mitarbeiter steht links. Welche Abfrage passt?
Lösung: FROM Mitarbeiter AS M LEFT JOIN Kunde AS K ON M.Bedient = K.KundeID — Der LEFT JOIN erhält alle Zeilen der linken Tabelle und setzt fehlende Kundendaten auf NULL.
Frage 3 von 4SchwerEine Abfrage soll alle Abteilungen zeigen, auch Abteilungen ohne Mitarbeiter. Welche Entscheidung ist entscheidend?
Lösung: Die Tabellenseite mit den Abteilungen muss durch den gewählten Outer Join vollständig erhalten bleiben. — Steht Abteilung links, passt ein LEFT JOIN; steht sie rechts, passt ein RIGHT JOIN. Entscheidend ist die zu erhaltende Seite.
Frage 4 von 4SchwerWarum ist NATURAL JOIN bei späteren Schemaänderungen riskanter als eine ausdrückliche ON-Bedingung?
Lösung: Neue gleichnamige Spalten werden automatisch zusätzlich verglichen. — NATURAL JOIN leitet seine gesamte Bedingung aus den aktuell gleichnamigen Spalten ab. Eine Schemaänderung kann daher unbemerkt das Ergebnis verändern.

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?

Passend dazu

9 Kapitel

Kapitel 1