SQL Lektion 3: JOIN
Lösung geprüft
Die Aufgabe der heutigen Stunde ist die dritte SQL-Lektion, und die ist die wichtigste von allen: JOIN. Bisher haben wir immer nur aus einer Tabelle gelesen. Der ganze Sinn einer relationalen Datenbank ist aber, dass die Daten auf mehrere Tabellen verteilt sind – und JOIN führt sie wieder zusammen.
a) Bearbeiten Sie die dritte Lektion und erstellen Sie in ihrem
OneNote-Heft eine kompakte übersichtliche Kurzzusammenfassung der
SQL-Befehle.
b) Bearbeiten Sie die Übung 3
Warum man JOIN braucht
Erinner dich an die Wurstsorten: der Lieferant steht nicht in der
Wursttabelle, dort steht nur seine Lieferant_ID. Will man
wissen, wie der Lieferant heißt, muss man in die andere Tabelle
schauen. Genau das macht JOIN.
Die beiden Schreibweisen
-- Zusammenfassung der dritten SQL-Lektion: JOIN
-- @meininfokurs.cmrg.site
-- Schreibweise 1: INNER JOIN ... ON (die modernere, empfohlene)
SELECT Wurstsorten.Sorte_Name, Lieferanten.Name
FROM Wurstsorten
INNER JOIN Lieferanten
ON Wurstsorten.Lieferant_ID = Lieferanten.ID;
-- Schreibweise 2: beide Tabellen in FROM, Bedingung in WHERE
SELECT Wurstsorten.Sorte_Name, Lieferanten.Name
FROM Wurstsorten, Lieferanten
WHERE Wurstsorten.Lieferant_ID = Lieferanten.ID;
Beide liefern dasselbe Ergebnis. Die erste Schreibweise ist die bessere,
weil man Verknüpfungsbedingung und Filterbedingung
auseinanderhalten kann: was zusammengehört steht bei
ON, was gefiltert wird bei WHERE. Bei der zweiten
steht beides vermischt im WHERE.
WHERE-Bedingung,
bekommst du das Kreuzprodukt: jede Zeile der einen
Tabelle wird mit jeder Zeile der anderen kombiniert. Bei 100 Wurstsorten
und 20 Lieferanten sind das 2000 Zeilen Unsinn. Bei INNER JOIN
kann das nicht passieren, weil ohne ON schon die Syntax
meckert.
Der Punkt zwischen Tabelle und Spalte
SELECT Wurstsorten.ID, Lieferanten.ID -- beide Tabellen haben eine Spalte ID
Sobald zwei Tabellen im Spiel sind, können Spaltennamen doppelt
vorkommen. Dann muss man Tabelle.Spalte schreiben, sonst
kommt Column 'ID' in field list is ambiguous. Bei eindeutigen
Namen darf man den Punkt weglassen – ich schreibe ihn trotzdem immer hin,
weil man dann sofort sieht, woher eine Spalte kommt.
Kürzere Namen mit AS
SELECT w.Sorte_Name, l.Name AS Lieferant
FROM Wurstsorten AS w
INNER JOIN Lieferanten AS l
ON w.Lieferant_ID = l.ID;
Das AS kennen wir schon aus Lektion 1 fürs Umbenennen von
Spalten. Es funktioniert auch für Tabellen und spart bei langen Namen
viel Tipparbeit.
Mehr als zwei Tabellen
-- Wurstsorte, Lieferant und dessen Ort - ueber drei Tabellen
SELECT w.Sorte_Name, l.Name AS Lieferant, o.Ortname
FROM Wurstsorten AS w
INNER JOIN Lieferanten AS l ON w.Lieferant_ID = l.ID
INNER JOIN Orte AS o ON l.Postleitzahl = o.Postleitzahl;
Man hängt einfach einen weiteren INNER JOIN an. Damit löst
man die Ketten auf, die bei den Eltern-Kind-Tabellen aufgetaucht sind –
etwa vom Schüler über den Ort bis zum Bundesland.
Das n:m-Problem
Bei einer Verknüpfungstabelle wie schueler_hat_lehrer
braucht man drei Tabellen im JOIN, obwohl man nur zwei
Sachen sehen will:
SELECT s.vorname, s.nachname, l.nachname AS Lehrer
FROM schueler AS s
INNER JOIN schueler_hat_lehrer AS shl ON s.id = shl.schueler
INNER JOIN lehrer AS l ON shl.lehrer = l.id;
Die Verknüpfungstabelle in der Mitte enthält selbst nichts Interessantes – sie ist nur die Brücke. Man muss trotzdem über sie gehen, weil es keine direkte Verbindung zwischen Schülern und Lehrern gibt.
Was INNER bedeutet
INNER JOIN liefert nur Zeilen, zu denen es auf
beiden Seiten einen Partner gibt. Eine Wurstsorte ohne
eingetragenen Lieferanten fällt raus – lautlos, ohne Fehlermeldung.
Genau daran hängt der häufigste „aber es fehlen Zeilen"-Fehler. Will man
auch die Partnerlosen sehen, nimmt man LEFT JOIN: der behält
alle Zeilen der linken Tabelle und füllt die fehlenden Spalten mit NULL.
Für den Grundkurs reicht INNER JOIN, aber wissen sollte man
es.
| JOIN-Art | Liefert |
|---|---|
INNER JOIN | nur Zeilen mit Partner auf beiden Seiten |
LEFT JOIN | alle Zeilen der linken Tabelle, fehlende Partner werden NULL |
RIGHT JOIN | umgekehrt |