![]() |
Fortgeschrittene Jointechniken:
|
|
| |
Im vorhergehenden Abschnitt haben Sie für Ihre Marketingabteilung die Kundennummern der Kunden herausgefunden, die sowohl über eine 'Mastercard' als auch eine 'American Express' verfügen. Nun möchte die Marketingabteilung wissen, um welche Person es sich handelt, d.h. Vorname, Nachname, Anschrift, … Diese Aufgabe können Sie mit einer SQL-Anweisung lösen, indem Sie einen Mehrfachjoin verwenden:
SELECT KK1.KndNr, Vorname, Nachname, Strasse, PLZ, Ort FROM (Kreditkarten AS KK1 INNER JOIN Kreditkarten AS KK2 ON KK1.KndNr = KK2.KndNr) INNER JOIN Kunden ON KK1.KndNr = Kunden.KndNr WHERE KK1.Firma = 'Mastercard' AND KK2.Firma = 'American Express' KndNr Vorname Nachname Strasse PLZ Ort ----------- ---------- ------------ --------------- ----- --------------- 123459 Schmidt Hans Hauptstraße 2 98765 Anderswo (1 row(s) affected)
Aus der Anweisung vom vorhergenden Beispiel wurden die nicht benötigten Spalten (2x Firma, KK2.KndNr) gestrichen, siehe auch die dortige Abschlussbemerkung. Durch den zweiten INNER JOIN wird das Ergebnis der ersten JOIN-Operation mit der Tabelle "Kunden" verknüpft. Wiederum dient die Spalte KndNr zur Verknüpfung. Ihre Marketingabteilung ist glücklich, sie hat genau die benötigten Daten für das geplante Mailing.
Die SQL-Syntax weist klare Richtlinien für die Reihenfolge der einzelnen Klauseln auf. Die WHERE-Klausel kommt (lange) nach der JOIN-Klausel. Deswegen kann die zweite JOIN-Klausel nicht einfach an die bisherige Anweisung angehängt werden.
Bei beiden JOIN-Operationen im vorliegenden Beispiel handelt es sich jeweils um einen INNER JOIN. Wie Sie dem Grundlagenartikel von Rouven Thimm entnehmen können, ist beim INNER JOIN die Reihenfolge der Operanden, d.h. der am JOIN beteiligten Tabellen irrelevant. D.h. statt FROM (Kreditkarten AS KK1 INNER JOIN Kreditkarten AS KK2) INNER JOIN Kunden hätte man genausogut FROM Kunden INNER JOIN (Kreditkarten AS KK1 INNER JOIN Kreditkarten KK2) schreiben können, ON-Klausel mal vernachlässigt. Da KK1.KndNr den gleichen Wert besitzt wie KK2.KndNr ist es auch unwichtig, welche dieser beiden Spalten für die äußere JOIN-Bedingung verwendet wird. Die Klammern (hinter FROM und nach der ersten ON-KLausel) legen die Reihenfolge der JOIN-Operationen fest. Verzichten Sie auf Klammern, so entscheidet das Datenbankmanagementsystem (DBMS), in welcher Reihenfolge es die JOINs abarbeitet.
Die Marketingabteilung hat schon wieder einen Auftrag für Sie: Diesmal benötigt sie die Adressen von allen Kunden, von den Kreditkarteninhabern zusätzlich die Kreditkarteninformationen aber nur, wenn sie Mitglied im Vorteilsclub sind. Ihnen ist klar, dass Sie für die Lösung dieser Aufgabe die Tabellen 'Kunden', 'Kreditkarten' und 'Vorteilsclub' miteinander verknüpfen müssen:
In einem ersten Zwischenschritt ermitteln Sie die Kreditkarteninformationen der Mitglieder des Vorteilsclub:
SELECT Kreditkarten.KndNr, Firma, KartenNr, Ablaufdatum FROM Kreditkarten INNER JOIN Vorteilsclub ON Kreditkarten.KndNr = Vorteilsclub.KndNr KndNr Firma KartenNr Ablaufdatum ----------- ------------------ ----------- ----------- 123458 Diners Club 12348 03/2008 123458 VISA 12349 07/2007 (2 row(s) affected)
Der Kunde muss über eine Kreditkarte verfügen, somit seine Kundennummer in der Tabelle "Kreditkarten" aufgeführt sein; gleiches gilt für den Vorteilsclub. Somit liefert der INNER JOIN dieser beiden Tabellen die Kreditkarteninformationen der Mitglieder im Vorteilsclub. In diesem Fall ist es ein einziger Kunde, der über zwei Kreditkarten verfügt.
Beachten Sie: Obwohl Sie überhaupt keine Spalte aus der Tabelle "Vorteilsclub" in der Ergebnistabelle verwenden, wird die Ergebnismenge durch den JOIN bereits eingeschränkt.
Das Ergebnis dieses Zwischenschrittes müssen Sie nun noch auf geeignete Weise mit der Tabelle "Kunden" verknüpfen. Da sie von sämtlichen Kunden die Detaildaten von "Kunden" benötigen, auch wenn keine Entsprechungen in der Menge der Kreditkarteninformationen (der Vorteilsclubmitglieder) vorliegen, können Sie diese Aufgabe z.B. mit einem LEFT JOIN der Tabellen "Kunden" und dem Zwischenergebnis lösen:
SELECT Kunden.KndNr, Vorname, Nachname, Strasse, PLZ, Ort, Firma, KartenNr, Ablaufdatum FROM Kunden LEFT JOIN (Kreditkarten INNER JOIN Vorteilsclub ON Kreditkarten.KndNr = Vorteilsclub.KndNr) ON Kunden.KndNr = Kreditkarten.KndNr KndNr Vorname Nachname Strasse PLZ Ort Firma KartenNr Ablaufdatum ----------- ---------- ------------ --------------- ----- --------------- ------------------ ----------- ----------- 123456 Mustermann Max Musterweg 1 12345 Musterstadt NULL NULL NULL 123457 Musterfrau Katrin Musterstraße 7 12345 Musterstadt NULL NULL NULL 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo Diners Club 12348 03/2008 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo VISA 12349 07/2007 123459 Schmidt Hans Hauptstraße 2 98765 Anderswo NULL NULL NULL 123460 Becker Heinz Mustergasse 4 12543 Musterdorf NULL NULL NULL (6 row(s) affected)
Im ersten Schritt erhalten Sie durch den INNER JOIN der Tabellen "Kreditkarten" und "Vorteilsclub" eine Tabelle derjenigen Kunden (genauer Kundennummern der Kunden), die sowohl Kreditkarteninhaber sind als auch dem Vorteilsclub angehören. Die Aufgabe, die Adressdaten aller Kunden, die Kreditkarteninformationen nur des gewünschten Kundenkreises auszugeben, wird vom äußeren LEFT JOIN der Tabelle "Kunden" mit dem Ergebnis der inneren Verknüpfung erledigt.
Sobald ein LEFT oder RIGHT JOIN im Spiel ist, ist die Reihenfolge der Tabellen, die Auswahl der JOIN-Spalten, ja sogar der JOIN-Operationen von Relevanz. Zur Illustration dieser Tatsache werden nun Variationen der gleichen JOIN-Operationen vorgestellt, die alle eines gemeinsam haben: sie liefern nicht das gewünschte Ergebnis.
Eine einfache Vertauschung der beiden 'Partner' des äußeren LEFT JOIN führt dazu, dass viele gewünschte Datensätze verloren gehen:
SELECT Kunden.KndNr, Vorname, Nachname, Strasse, PLZ, Ort, Firma, KartenNr, Ablaufdatum FROM (Kreditkarten INNER JOIN Vorteilsclub ON Kreditkarten.KndNr = Vorteilsclub.KndNr) LEFT JOIN Kunden ON Kunden.KndNr = Kreditkarten.KndNr KndNr Vorname Nachname Strasse PLZ Ort Firma KartenNr Ablaufdatum ----------- ---------- ------------ --------------- ----- --------------- ------------------ ----------- ----------- 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo Diners Club 12348 03/2008 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo VISA 12349 07/2007 (2 row(s) affected)
Das Verhalten des LEFT JOIN ist hier im Mehrfachjoin ganz analog zum Verhalten beim einfachen LEFT JOIN, wie in Rouven Thimms Artikel beschrieben. Beim LEFT JOIN spielt die Reihenfolge der beteiligten Tabellen eine Rolle. Dies gilt auch dann, wenn eine der beteiligten Tabellen das Ergebnis einer weiteren JOIN-Operation ist.
Im nächsten Beispiel wird die Reihenfolge der Operationen verändert: zuerst ein LEFT JOIN von "Kunden" und "Kreditkarten", anschließend ein INNER JOIN mit dem Vorteilsclub.
SELECT Kunden.KndNr, Vorname, Nachname, Strasse, PLZ, Ort, Firma, KartenNr, Ablaufdatum FROM (Kunden LEFT JOIN Kreditkarten ON Kunden.KndNr = Kreditkarten.KndNr) INNER JOIN Vorteilsclub ON Kreditkarten.KndNr = Vorteilsclub.KndNr KndNr Vorname Nachname Strasse PLZ Ort Firma KartenNr Ablaufdatum ----------- ---------- ------------ --------------- ----- --------------- ------------------ ----------- ----------- 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo Diners Club 12348 03/2008 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo VISA 12349 07/2007 (2 row(s) affected)
Das Ergebnis ist das gleiche wie im vorhergenden Beispiel, was an den vorhandenen Daten liegt. Im allgemeinen Fall können aus beiden Abfragen unterschiedliche Ergebnistabellen resultieren. Zuerst werden jedem Kunden Kreditkarteninformationen zugeordnet, so welche vorhanden sind, der INNER JOIN filtert die Kombinationen aus, die auch Mitglied im Vorteilsclub sind.
Im nächsten Beispiel ändern wir nur ein Detail gegenüber dem vorhergehenden: Statt die Kundennummer der Tabelle "Kreditkarten" für den INNER JOIN zu verwenden, wird die Spalte der Tabelle "Kunden" verwendet:
SELECT Kunden.KndNr, Vorname, Nachname, Strasse, PLZ, Ort, Firma, KartenNr, Ablaufdatum FROM (Kunden LEFT JOIN Kreditkarten ON Kunden.KndNr = Kreditkarten.KndNr) INNER JOIN Vorteilsclub ON Kunden.KndNr = Vorteilsclub.KndNr KndNr Vorname Nachname Strasse PLZ Ort Firma KartenNr Ablaufdatum ----------- ---------- ------------ --------------- ----- --------------- ------------------ ----------- ----------- 123456 Mustermann Max Musterweg 1 12345 Musterstadt NULL NULL NULL 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo Diners Club 12348 03/2008 123458 Müller Lieschen Beispielweg 3 23987 Irgendwo VISA 12349 07/2007 123460 Becker Heinz Mustergasse 4 12543 Musterdorf NULL NULL NULL (4 row(s) affected)
Bei der Verwendung eines LEFT/RIGHT JOIN und Weiternutzung des Zwischenergebnisses dieser Operation in einem weiteren JOIN mit gemeinsamer JOIN-Spalte ist es von Belang, welche der beiden Spalten man für den weiteren JOIN nutzt. Sinnvollerweise nutzt man in solchen Fällen die Spalte, die keine NULL-Werte enthalten.
Mehrfachjoins sind nützliche Tehniken in Datenbankanwendungen. Dieser Abschnitt zeigte die grundlegende Vorgehensweise zum Verständnis des Mehrfachjoins auf. Zerlegen Sie das Problem in einzelne JOIN-Operationen. Da das Ergebnis einer JOIN-Operation wiederum eine Tabelle ist, verwenden Sie ein solches Ergebnis wie eine Tabelle in einer weiteren JOIN-Operation.
Sobald LEFT oder RIGHT JOINs in einem Mehrfachjoin auftreten, ist die Reihenfolge von Relevanz. Dies wurde an ausgewählten Beispielen demonstriert. Bereits bei nur drei beteiligten Tabellen mit gemeinsamer JOIN-Spalte und nur den Operationen INNER JOIN und LEFT JOIN gibt es insgesamt 45 verschiedene Möglichkeiten einen Mehrfachjoin zu formulieren mit 16 verschiedenen Ergebnissen. Diese im einzelnen auch nur aufzuführen, würde den Rahmen dieses Artikels sprengen, die ständige Wiederholung fast gleicher SQL-Anweisungen wäre ebenso anstrengend wie langweilig. [To do:] Für den interessierten Nutzer ist im Anhang ein SQL-Skript mit allen 45 Möglichkeiten und den erforderlichen Beispieltabellen verlinkt.
Die Analyse der Aufgabenstellung, d.h. welche Datensätze sollen zurückgegeben werden, führt jedoch meist schnell zum richtigen Ergebnis, wie die ersten beiden Beispiele in diesem Abschnitt aufzeigen. In vielen Fällen sind beim Mehrfachjoin die Tabellen nicht über ein einziges gemeinsames Spalte verknüpft, sondern über unterschiedliche Spalten. Der nächste Abschnitt beschäftigt sich mit dieser Aufgabenstellung.
© 2007
Impressum, für diese Seite:
vinzenzmai@web.de