Aus Wikibooks
Dieses Kapitel enthält die Einführung in den "modernen" Weg, mehrere Tabellen gleichzeitig abzufragen. Dazu wird jede verknüpfte Tabelle in einer JOIN-Klausel aufgeführt; der ON-Parameter enthält die Verknüpfungsbedingung. Die WHERE-Klausel enthält "nur" die Auswahlbedingungen.
[Bearbeiten] Die Syntax von JOIN
Um Tabellen sinnvoll miteinander zu verknüpfen (= verbinden, engl. join), wurde die JOIN-Klausel für den SELECT-Befehl mit folgender Syntax eingeführt.
SELECT <spaltenliste>
FROM <haupttabelle>
[<join-typ>] JOIN <verknüpfte tabelle> ON <bedingung>
Als <join-typ> stehen zur Verfügung:
- [INNER] JOIN, auch Equi-Join genannt, bezeichnet Verknüpfungen "innerhalb" zweier Tabellen, d.h. einen Teil des kartesischen Produkts, bei dem ein Wert in beiden Tabellen vorhanden ist. INNER JOIN ist der Inhalt dieses Kapitels.
- OUTER JOIN bezeichnet Verknüpfungen, bei denen auch Datensätze geliefert werden, für die eine Vergleichsbedingung nicht erfüllt ist.
- LEFT JOIN, RIGHT JOIN, FULL JOIN bezeichnen Spezialfälle von OUTER JOIN, je nachdem in welcher Tabelle ein gesuchter Wert fehlt.
OUTER JOIN wird im nächsten Kapitel behandelt.
Einige Sonderfälle von JOIN werden in Mehr zu JOIN behandelt.
Als <bedingung> wird normalerweise nur eine Übereinstimmung (also eine Gleichheit) zwischen zwei Tabellen geprüft, auch wenn theoretisch jede Kombination von Bedingungen erlaubt wäre. Genauer: es geht um die Gleichheit von Werten je einer Spalte in zwei Tabellen. Auch mehrere Verknüpfungen sind möglich, entweder direkt hintereinander:
SELECT <spaltenliste>
FROM <haupttabelle>
[<join-typ>] JOIN <zusatztabelle1> ON <bedingung1>
[<join-typ>] JOIN <zusatztabelle2> ON <bedingung2>
[<join-typ>] JOIN <zusatztabelle3> ON <bedingung3>
oder durch Klammern gegliedert:
SELECT <spaltenliste>
FROM <haupttabelle>
[<join-typ>] JOIN
( <zusatztabelle1>
[<join-typ>] JOIN
( <zusatztabelle2>
[<join-typ>] JOIN <zusatztabelle3> ON <bedingung3>
) ON <bedingung2>
) ON <bedingung1>
Bitte beachten Sie, dass diese Varianten unterschiedliche Ergebnisse liefern können - abhängig vom JOIN-Typ und dem Zusammenhang zwischen den Tabellen.
Alle diese Möglichkeiten werden in den nächsten Abschnitten und Kapiteln genauer erläutert.
[Bearbeiten] INNER JOIN von zwei Tabellen
Das Beispiel "alle Mitarbeiter mit den zugehörigen Dienstwagen" aus
Einfache Tabellenverknüpfung benötigt nur geringe Änderungen.
SQL-Quelltext:
SELECT
mi.Personalnummer AS MitNr,
mi.Name, mi.Vorname,
dw.ID, dw.Kennzeichen, dw.Fahrzeugtyp_ID AS Typ
FROM Mitarbeiter mi
JOIN Dienstwagen dw ON dw.Mitarbeiter_ID = mi.ID
ORDER BY MitNr;
Das Ergebnis dieser Abfrage ist identisch mit der Liste im vorigen Kapitel; ich verzichte deshalb auf die erneute Ausgabe.
[Bearbeiten] WHERE-Klausel bei JOINs
Eine solche Abfrage kann wie üblich durch eine WHERE-Klausel auf bestimmte Datensätze eingeschränkt werden. Wenn sich eine solche Suchbedingung auf die verknüpfte Tabelle Dienstwagen bezieht, kann man sie sowohl über die WHERE-Klausel als auch über die JOIN-Klausel einbauen. In den beiden folgenden Beispielen geht es nur um die Dienstwagen von Mercedes. Die Information, welche Typen zu Mercedes gehören, kommt über eine Unterabfrage, die ebenfalls einen JOIN verwendet und die in Klammern gesetzt ist.
Suche die Dienstwagen vom Typ
Mercedes.
Zulässig, aber nicht so schön, weil Vergleichsbedingung und Auswahlbedingung vermischt werden
SQL-Quelltext:
SELECT
mi.Personalnummer AS MitNr,
mi.Name, mi.Vorname,
dw.ID, dw.Kennzeichen, dw.Fahrzeugtyp_ID AS Typ
FROM Mitarbeiter mi
JOIN Dienstwagen dw
ON mi.ID = dw.Mitarbeiter_ID
AND dw.Fahrzeugtyp_ID IN ( SELECT ft.ID
FROM Fahrzeugtyp ft
JOIN Fahrzeughersteller fh
ON ft.Hersteller_ID = fh.ID
AND fh.Name = 'Mercedes-Benz' );
Besseres Vorgehen, weil die Auswahlbedingungen als solche direkt zu erkennen sind
SQL-Quelltext:
SELECT
mi.Personalnummer AS MitNr,
mi.Name, mi.Vorname,
dw.ID, dw.Kennzeichen, dw.Fahrzeugtyp_ID AS Typ
FROM Mitarbeiter mi
JOIN Dienstwagen dw
ON mi.ID = dw.Mitarbeiter_ID
WHERE dw.Fahrzeugtyp_ID IN ( SELECT ft.ID
FROM Fahrzeugtyp ft
JOIN Fahrzeughersteller fh
ON ft.Hersteller_ID = fhe.ID
WHERE fh.Name = 'Mercedes-Benz');
Natürlich sind Einschränkungen auf beide Tabellen möglich:
Gesucht werden die Mitarbeiter mit 'M' und Mercedes als Dienstwagen.
SQL-Quelltext:
SELECT
mi.Personalnummer AS MitNr,
mi.Name, mi.Vorname,
dw.ID, dw.Kennzeichen, dw.Fahrzeugtyp_ID AS Typ
FROM Mitarbeiter mi
JOIN Dienstwagen dw
ON mi.ID = dw.Mitarbeiter_ID
WHERE dw.Fahrzeugtyp_ID IN ( SELECT ft.ID
FROM Fahrzeugtyp ft
JOIN Fahrzeughersteller fh
ON ft.Hersteller_ID = fhe.ID
WHERE fh.Name = 'Mercedes-Benz')
AND mi.Name LIKE 'M%';
SQL-Ausgabe:
MITNR NAME VORNAME ID KENNZEICHEN TYP
10001 Müller Kurt 1 DO-WB 421 14
20001 Meyer Walter 2 DO-WB 422 14
Bei diesem Beispiel wird sofort deutlich, welche Bedingungen die Verknüpfung und welche Bedingungen die Auswahl bezeichnem. Auf diese Übersichtlichkeit sollten Sie immer achten.
Übrigens gibt es keine allgemeine Regel, was als Haupttabelle und was als verknüpfte Tabelle zu verwenden ist. In den bisherigen Beispielen können die beiden Tabellen ohne weiteres vertauscht werden:
Mitarbeiter mit 'M' und Mercedes als Dienstwagen
SQL-Quelltext:
SELECT
mi.Personalnummer AS MitNr,
mi.Name, mi.Vorname,
dw.ID, dw.Kennzeichen, dw.Fahrzeugtyp_ID AS Typ
FROM Dienstwagen dw
JOIN Mitarbeiter mi
ON mi.ID = dw.Mitarbeiter_ID
WHERE dw.Fahrzeugtyp_ID IN ( SELECT ft.ID
FROM Fahrzeugtyp ft
JOIN Fahrzeughersteller fh
ON ft.Hersteller_ID = fh.ID
WHERE fh.Name = 'Mercedes-Benz')
AND mi.Name LIKE 'M%';
Die Haupttabelle kann nach folgenden Überlegungen gewählt werden:
- Es sollte die Tabelle sein, die die "wichtigste" bei der Abfrage ist.
- Es sollte diejenige mit den größten Einschränkungen sein; das beschleunigt die Abfrage besonders stark.
[Bearbeiten] INNER JOIN mehrerer Tabellen
Für diese Situation unter Verwendung von JOIN verwende ich wiederum das komplexe Beispiel aus Einfache Tabellenverknüpfung, das unter Gruppierungen genauer besprochen wird. In diesem Fall spielt die Reihenfolge der JOIN-Klauseln eher keine Rolle, weil es sich sowieso um direkte Übereinstimmungen handelt und nur solche Datensätze benutzt werden, die es zu den betreffenden Werten tatsächlich gibt.
Gesucht wird für jeden
Fahrzeughersteller (mit Angabe von ID und Name) und jedes Jahr die Summe der Schadenshöhe aus der Tabelle
Schadensfall.
SQL-Quelltext:
SELECT fh.ID AS Hersteller_ID,
fh.Name AS Hersteller_Name,
EXTRACT(YEAR FROM sf.Datum) AS Jahr,
SUM(sf.Schadenshoehe) AS Schadenssumme
FROM Schadensfall sf
JOIN Zuordnung_SF_FZ zu ON sf.ID = zu.Schadensfall_ID
JOIN Fahrzeug fz ON fz.ID = zu.Fahrzeug_ID
JOIN Fahrzeugtyp ft ON ft.ID = fz.Fahrzeugtyp_ID
JOIN Fahrzeughersteller fh ON fh.ID = ft.Hersteller_ID
GROUP BY Hersteller_ID, Hersteller_Name, Jahr
ORDER BY Jahr, Hersteller_ID;
Übrigens ist es auch zulässig, den "traditionellen" Weg mit mehreren Tabellen in der FROM-Klausel und den "modernen" Weg über JOIN zu mischen. Wenn Sie in einem Ausnahmefall wirklich so vorgehen wollen, sollten Sie erst recht genau auf die Übersichtlichkeit und den Zusammenhang der Bedingungen achten (ich kann mir keine passende Situation vorstellen, aber vielleicht ist es auch einmal sinnvoll).
In diesem Kapitel lernten Sie die Verknüpfung von Tabellen über die JOIN-Klausel kennen.
- Mit einem INNER JOIN werden Datensätze abgefragt, bei denen ein Wert in je einer Spalte beider Tabellen vorhanden ist.
- In der ON-Klausel steht diese Verknüpfungsbedingung.
- In der WHERE-Klausel stehen die "normalen" Auswahlbedingungen.
Genauso können mehrere Tabellen verknüpft werden.