Buchgenerator (deaktivieren)

Einführung in SQL: Arbeiten mit JOIN

Aus Wikibooks

Wechseln zu: Navigation, Suche


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.

Inhaltsverzeichnis

[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

Aufgabe
Das Beispiel "alle Mitarbeiter mit den zugehörigen Dienstwagen" aus Einfache Tabellenverknüpfung benötigt nur geringe Änderungen.

Crystal Clear app terminal.png 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.

Aufgabe
Suche die Dienstwagen vom Typ Mercedes.

Crystal Clear action button cancel.png Zulässig, aber nicht so schön, weil Vergleichsbedingung und Auswahlbedingung vermischt werden
Crystal Clear app terminal.png 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' );

Crystal Clear action apply.png Besseres Vorgehen, weil die Auswahlbedingungen als solche direkt zu erkennen sind
Crystal Clear app terminal.png 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:

Aufgabe
Gesucht werden die Mitarbeiter mit 'M' und Mercedes als Dienstwagen.

Crystal Clear app terminal.png 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%';

Crystal Clear app kscreensaver.png 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
Crystal Clear app terminal.png 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.

Aufgabe
Gesucht wird für jeden Fahrzeughersteller (mit Angabe von ID und Name) und jedes Jahr die Summe der Schadenshöhe aus der Tabelle Schadensfall.

Crystal Clear app terminal.png 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).



[Bearbeiten] Zusammenfassung

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.


Persönliche Werkzeuge