Alle Tabs der Lerneinheit (Erklärung · Interaktiv · Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Erklärung
Ein JOIN verknüpft zwei Tabellen über einen gemeinsamen Schlüssel, typisch Primary Key auf der einen, Foreign Key auf der anderen Seite. Statt zwei separate SELECTs auszuführen, holst du Daten aus mehreren Tabellen in einer einzigen Query.
Es gibt vier JOIN-Typen, die in deutschen Datenbank-Klausuren regelmäßig abgefragt werden:
- INNER JOIN: nur Zeilen mit Match in beiden Tabellen (Schnittmenge)
- LEFT JOIN: alle Zeilen aus der linken Tabelle, plus Matches rechts (NULL falls nichts matcht)
- RIGHT JOIN: alle Zeilen aus der rechten Tabelle, plus Matches links
- FULL OUTER JOIN: alle Zeilen aus beiden Tabellen, NULL wo nichts matcht
In Klausuren wirst du am häufigsten gefragt, welcher JOIN ein bestimmtes Ergebnis liefert. Das Mengen-Bild ist eine gute Merkhilfe (INNER = Schnittmenge, LEFT/RIGHT = ganze linke bzw. rechte Menge, FULL = Vereinigung), aber eine Vereinfachung: SQL-JOINs arbeiten mit Zeilenpaaren. Bei 1:n- oder n:m-Beziehungen kann ein Datensatz im Ergebnis mehrfach erscheinen, pure Mengenoperation greift dann zu kurz.
Das Problem
Du hast zwei Tabellen:
studierende studiengaenge
┌────┬───────┬─────────────┐ ┌────┬──────────────┐
│ id │ name │ sg_id (FK) │ │ id │ name │
├────┼───────┼─────────────┤ ├────┼──────────────┤
│ 1 │ Anna │ 1 │ │ 1 │ Informatik │
│ 2 │ Ben │ 2 │ │ 2 │ BWL │
│ 3 │ Clara │ 1 │ │ 3 │ WI │
└────┴───────┴─────────────┘ └────┴──────────────┘
Frage: "Welcher Studi studiert was?"
Mit zwei separaten SELECTs zu fummelig. Mit JOIN in einer Query:
SELECT s.name, sg.name AS studiengang
FROM studierende s
INNER JOIN studiengaenge sg ON s.sg_id = sg.id;
JOIN verknüpft zwei (oder mehr) Tabellen über einen gemeinsamen Schlüssel, typisch Primary Key ↔ Foreign Key.
Die 4 wichtigen JOIN-Typen
| Typ | Was er liefert |
|---|---|
| INNER JOIN | nur Zeilen mit Match in beiden Tabellen |
| LEFT JOIN | alle Zeilen aus der linken Tabelle + Matches |
| RIGHT JOIN | alle Zeilen aus der rechten Tabelle + Matches |
| FULL OUTER JOIN | alle Zeilen aus beiden Tabellen |
Klausur-Trick: Stell dir die Tabellen als Mengen vor. INNER = Schnittmenge, LEFT = ganze linke Menge, RIGHT = ganze rechte Menge, FULL = Vereinigung.
INNER JOIN, der Standard
SELECT s.name, sg.name
FROM studierende s
INNER JOIN studiengaenge sg ON s.sg_id = sg.id;
Was passiert: Jeder Studi wird zu seinem Studiengang verknüpft. Studis OHNE Studiengang fallen raus. Studiengänge OHNE Studis auch.
Result:
Anna | Informatik
Ben | BWL
Clara | Informatik
Häufigste Form in der Praxis. Wenn du nichts spezifizierst, ist meistens INNER JOIN gemeint.
LEFT JOIN, alle Zeilen links behalten
SELECT s.name, sg.name
FROM studierende s
LEFT JOIN studiengaenge sg ON s.sg_id = sg.id;
Was passiert: ALLE Studis sind im Result. Wenn ein Studi keinen passenden Studiengang hat → NULL.
Anna | Informatik
Ben | BWL
Clara | Informatik
Eva | NULL ← Studi ohne Studiengang
Wichtigster JOIN nach INNER. Klassisch wenn du sagst: "Zeig mir alle X, und wenn sie ein Y haben, dann auch das Y."
RIGHT JOIN, alle Zeilen rechts behalten
SELECT s.name, sg.name
FROM studierende s
RIGHT JOIN studiengaenge sg ON s.sg_id = sg.id;
Spiegelung von LEFT JOIN, alle Studiengänge sind drin, auch die ohne Studi.
Anna | Informatik
Ben | BWL
Clara | Informatik
NULL | Data Science ← Studiengang ohne Studi
In der Praxis selten: meistens schreibt man RIGHT JOIN als LEFT JOIN um (Tabellen tauschen). Konsistenter.
FULL OUTER JOIN, alles aus beiden
SELECT s.name, sg.name
FROM studierende s
FULL OUTER JOIN studiengaenge sg ON s.sg_id = sg.id;
ALLES aus beiden Tabellen. NULL wo kein Match.
Anna | Informatik
Ben | BWL
Clara | Informatik
Eva | NULL ← aus links
NULL | Data Science ← aus rechts
Selten gebraucht, aber wenn du wirklich ALLES sehen willst: FULL OUTER. Manche DBs (z.B. MySQL älter) unterstützen es nicht direkt, UNION von LEFT und RIGHT als Workaround.
Visualisierung als Mengen-Diagramm
L R
┌────────┬────────┐
│ A │ B │ A = nur in L (ohne Match)
│ │ │ B = nur in R (ohne Match)
├────────┼────────┤ C = in beiden (Match)
│ │ │
│ │ C │
│ │ │
└────────┴────────┘
INNER JOIN → C
LEFT JOIN → A + C
RIGHT JOIN → B + C
FULL OUTER → A + B + C
Mehrere JOINs verketten
In Praxis sind 2-5 JOINs üblich:
SELECT s.name, sg.name AS studiengang, k.titel AS klausur, b.note
FROM studierende s
INNER JOIN studiengaenge sg ON s.sg_id = sg.id
INNER JOIN belegungen b ON b.studi_id = s.id
INNER JOIN klausuren k ON b.klausur_id = k.id
WHERE s.semester >= 3;
Tipp: Aliase (
s,sg,k,b) machen den Code lesbar. Lange Tabellen-Namen jedes mal zu schreiben wird unübersichtlich.
ON vs. WHERE
-- ON: Verknüpfungs-Bedingung zwischen Tabellen
INNER JOIN studiengaenge sg ON s.sg_id = sg.id
-- WHERE: Filter NACH dem Join
WHERE s.semester >= 3
Nicht verwechseln: ON sagt WIE die Tabellen verbunden werden. WHERE filtert das Ergebnis.
USING, Kurzform
Wenn die Verknüpfungs-Spalte in beiden Tabellen den gleichen Namen hat:
-- Statt:
INNER JOIN klausuren k ON s.klausur_id = k.klausur_id
-- Kurzform:
INNER JOIN klausuren k USING (klausur_id)
Fast dieselbe Bedeutung. Unterschied: Bei USING (klausur_id) erscheint die Join-Spalte im Ergebnis nur einmal zusammengeführt; bei ON a.klausur_id = b.klausur_id mit SELECT * können beide Spalten separat im Ergebnis stehen. USING ist optional und wird nicht von allen DBs unterstützt.
Self-Join, eine Tabelle mit sich selbst
Klausur-Klassiker. Du hast eine mitarbeiter-Tabelle mit vorgesetzter_id als Foreign Key auf dieselbe Tabelle:
SELECT a.name AS angestellter, b.name AS vorgesetzter
FROM mitarbeiter a
LEFT JOIN mitarbeiter b ON a.vorgesetzter_id = b.id;
Aliase sind hier Pflicht (
aundb), sonst weiß die DB nicht welche Spalte gemeint ist.
Klausur-Tricks
Trick 1, INNER vs. OUTER: alle JOINs außer INNER sind "OUTER" (LEFT, RIGHT, FULL OUTER). LEFT JOIN = LEFT OUTER JOIN, kann beides geschrieben werden.
Trick 2, Mengen-Bild merken:
INNER → ∩ (Schnittmenge)
LEFT → L (linke ganze Menge + Schnittmenge)
RIGHT → R (rechte ganze Menge + Schnittmenge)
FULL → ∪ (Vereinigung)
Trick 3, RIGHT in LEFT umschreiben:
A RIGHT JOIN B ON ...
-- ist gleich
B LEFT JOIN A ON ...
Tabellen-Reihenfolge tauschen, dann LEFT statt RIGHT.
Trick 4, NULL bei OUTER JOINs: bei LEFT/RIGHT/FULL erscheinen NULL-Werte für nicht-gematchte Zeilen. Mit WHERE x IS NULL kannst du gezielt nach "alle Linken OHNE Right-Match" suchen, sehr nützlich für "fehlende" Daten.
-- Studis OHNE Studiengang finden:
SELECT s.name
FROM studierende s
LEFT JOIN studiengaenge sg ON s.sg_id = sg.id
WHERE sg.id IS NULL;
Trick 5, Cartesian Product (Cross Join) ist gefährlich:
SELECT * FROM tabelleA, tabelleB -- jede mit jeder!
Wenn du die ON-Klausel vergisst, multiplizieren sich die Zeilen. Bei 1000×1000 = 1 Million Zeilen. Klausur-Falle.
Trick 6, JOIN ist nicht symmetrisch bei OUTER:
A LEFT JOIN B ≠ B LEFT JOIN A
INNER JOIN ist symmetrisch (Schnittmenge ist gleich), OUTER nicht.
Trick 7, Performance: JOINs können stark von Indexen auf Join-Spalten profitieren, Foreign Keys + indexierte Primary Keys ist Standard. Ob ein Index tatsächlich genutzt wird, entscheidet der Optimizer anhand von Statistiken, Selektivität und Datenmenge. Ohne Index: häufig Full Table Scan = langsam.
Trick 8, Mehrere Bedingungen in ON:
INNER JOIN aufgaben a
ON s.id = a.studi_id AND a.semester = 'WS24'
Erlaubt komplexere Verknüpfungen.
Trick 9, JOIN-Reihenfolge: Bei INNER JOINs kann der Optimizer die physische Auswertungsreihenfolge meist umordnen. Bei OUTER JOINs, Filtern auf der äußeren Seite und komplexen Subqueries ist die geschriebene Reihenfolge logisch wichtig und kann auch die Performance beeinflussen. Klausurrelevant: Bei LEFT JOIN ... WHERE rechte_tabelle.spalte = X werden die unmatched NULL-Zeilen entfernt, der LEFT JOIN wirkt dann faktisch wie INNER. Die Bedingung in ON statt WHERE umgeht das.
Trick 10, WHERE statt ON bei OUTER ändert das Ergebnis:
-- LEFT JOIN behält alle Studis, auch ohne sg
LEFT JOIN sg ON s.sg_id = sg.id WHERE sg.name = 'Informatik'
-- → wird zu INNER JOIN, weil WHERE die NULLs rausfiltert!
-- Korrekt: Bedingung in ON:
LEFT JOIN sg ON s.sg_id = sg.id AND sg.name = 'Informatik'
Klausur-Klassiker zum Verständnis.
Wo brauchst du JOINs?
- JEDE relationale DB-Anwendung: Bestellungen + Kunden, Posts + Autoren, Produkte + Kategorien
- Reporting: Umsätze pro Kunde pro Monat = JOIN über Bestellungen + Kunden
- Data Warehouses: Star-Schema mit Fact + Dimensions (alles JOIN)
- OLAP / BI: viele JOINs für komplexe Analysen
- API-Endpoints:
/api/users/:id/ordersmacht intern JOIN
Faustregel: relationale DBs sind FÜR JOINs gemacht. Wenn du kein JOIN brauchst → vielleicht ist eine andere Datenstruktur (Document, Key-Value) besser.
Interaktiv
Joins-Lab
Im Interaktiv-Lab nutzen wir einen erweiterten Datensatz: Anna, Ben, Clara, David (alle mit Match), Eva (ohne Studiengang) und ein Studiengang Data Science ohne Studi. So zeigen alle 4 JOIN-Typen unterschiedliche Resultate.
Was du tun kannst:
- Wähle den JOIN-Typ (INNER / LEFT / RIGHT / FULL)
- Sieh sofort welche Zeilen aus den Quell-Tabellen ins Ergebnis kommen, Akzent-Tönung = drin, Grau-Tönung = raus
- Die generierte SQL-Query wird oben gezeigt
- Result-Set unten mit NULL-Werten markiert
Probier folgendes:
- INNER JOIN → 4 Zeilen (Anna, Ben, Clara, David). Eva und Data Science fallen raus.
- LEFT JOIN → 5 Zeilen. Eva ist drin mit NULL-Studiengang.
- RIGHT JOIN → 5 Zeilen. Data Science ist drin mit NULL-Studi.
- FULL OUTER JOIN → 6 Zeilen. Alles drin.
Die Mengen-Logik wird sichtbar: INNER = Schnittmenge, FULL = Vereinigung.
Interaktive Visualisierung
Visualisiert INNER, LEFT, RIGHT, FULL JOIN auf zwei Tabellen mit hervorgehobenen Zeilen.
Faustregel zum Mitnehmen: INNER für die Schnittmenge, LEFT für "alles aus links + matched aus rechts". In der Praxis sind das die zwei häufigsten, RIGHT und FULL OUTER eher selten.
Quiz
Klausurfragen mit Lösungen (8)
- F1.Welcher JOIN-Typ liefert nur Zeilen mit Treffer in beiden Tabellen?
Antwort: INNER JOIN
Erklärung: INNER JOIN liefert die Schnittmenge, nur Zeilen, die in beiden Tabellen einen Match haben. Das ist der häufigste JOIN. Alle anderen sind 'OUTER JOINs' und behalten auch unmatched Zeilen.
- F2.Tabelle A hat 5 Zeilen, davon 3 mit passendem Match in B. B hat 4 Zeilen, davon 3 matched. Wieviele Zeilen liefert A LEFT JOIN B?
Antwort: 5
Erklärung: LEFT JOIN behält ALLE Zeilen aus A. Die 5 A-Zeilen sind alle drin: 3 mit Match (Daten aus B), 2 ohne Match (NULL für B-Spalten). Die unmatched B-Zeile fällt raus.
Typ: Zahlen-Eingabe
- F3.Was ist der Unterschied zwischen ON und WHERE?
Antwort: ON sagt wie die Tabellen verknüpft werden, WHERE filtert das Ergebnis
Erklärung: ON definiert die Verknüpfungs-Bedingung: 'Welche Zeilen aus A passen zu welchen aus B?'. WHERE filtert das ENDERGEBNIS. Bei OUTER JOINs ist der Unterschied wichtig, WHERE auf NULL-Spalten wandelt LEFT JOIN faktisch in INNER JOIN um.
- F4.Du willst alle Studierenden listen, auch wenn sie keinen Studiengang haben. Welcher JOIN?
Antwort: LEFT JOIN (mit studierende links)
Erklärung: LEFT JOIN behält alle Zeilen aus der linken Tabelle. Wenn studierende links steht: alle Studis erscheinen, mit NULL für Studis ohne Studiengang. Sehr häufiges Pattern: 'zeig alle X, plus deren optionale Y'.
- F5.Welche Aussage über RIGHT JOIN ist korrekt?
Antwort: Lässt sich als LEFT JOIN umschreiben durch Tauschen der Tabellen-Reihenfolge
Erklärung: RIGHT JOIN ist seltener, meistens schreibt man äquivalent LEFT JOIN nach Tabellen-Tausch: 'A RIGHT JOIN B' = 'B LEFT JOIN A'. Beide liefern dasselbe. Mit LEFT-Konvention bleibt der Code konsistent.
- F6.Was passiert beim CROSS JOIN (oder JOIN ohne ON-Klausel)?
Antwort: Cartesian Product: jede Zeile von A mit jeder Zeile von B verknüpft
Erklärung: CROSS JOIN bzw. die alte Komma-Schreibweise FROM A, B (ohne WHERE-Verknüpfung) erzeugt ein CARTESIAN PRODUCT: m × n Zeilen, jede aus A mit jeder aus B kombiniert. Bei 1000×1000 = 1 Million Zeilen. Bei explizitem INNER JOIN ohne ON/USING ist das Verhalten dialektabhängig, manche DBs verlangen die Bedingung. Häufige Anfänger-Falle: ON vergessen.
- F7.Wie findest du Studierende OHNE zugewiesenen Studiengang?
Antwort: LEFT JOIN studiengaenge ON ..., dann WHERE sg.id IS NULL
Erklärung: Anti-Join Pattern: LEFT JOIN macht alle Studis sichtbar (auch ohne Match), dann WHERE sg.id IS NULL filtert genau die ohne Match. Klassisches SQL-Idiom für 'fehlende' Daten. Antwort A funktioniert nicht (NULL braucht IS NULL). Antwort B liefert nichts, INNER JOIN hat keine NULLs.
- F8.Wieviele Zeilen liefert ein FULL OUTER JOIN zwischen A (5 Zeilen, 3 matched) und B (4 Zeilen, 3 matched)?
Antwort: 6
Erklärung: FULL OUTER JOIN = alles aus beiden + NULL wo kein Match. 3 matched + 2 unmatched aus A + 1 unmatched aus B = 6 Zeilen. Jede unmatched Zeile erscheint einmal mit NULLs auf der anderen Seite.
Typ: Zahlen-Eingabe