13 Ergänzungen zu COUNT and JOIN

Werbung
150.422
13
Datenbanken – SQL Handout 8
Ergänzungen zu COUNT and JOIN
• Zählen für Fortgeschrittene •
Allgemein zählt COUNT(col1 ,. . . ,coln ) jene Zeilen, in denen col1 ,. . . ,coln nicht alle NULL sind.
B Beispiel. Zeige für jedes Land die Anzahl von Lieferanten aus diesem Land, die über eine Webseite
verfügen.
1
SELECT S_Country , COUNT ( S_Website ) FROM Supplier
GROUP BY 1
Man beachte, dass im Ergebnis auch jene Länder angeführt sind, in denen es keine Lieferanten mit
Webseite gibt.
Möchte man nur Zeilen zählen, in denen eine bestimmte Bedingung erfüllt ist, kann dies mit einer
passenden WHERE Bedingung bewerkstelligt werden. Allerdings gehen dabei jene Zeilen verloren, wo der
COUNT=0 ist.
B Beispiel. Zeige für jedes Land die Anzahl der Lieferanten mit einer Bewertung D.
3
SELECT S_Country , COUNT (*) FROM Supplier
WHERE S_Evaluation = ’D ’
GROUP BY 1
Anders als im vorhergehenden Beispiel werden Länder ohne entsprechende Lieferanten nicht angezeigt.
Der einfachste Weg, dieses Problem zu beheben, ist, ein entsprechendes IF oder CASE anstelle der
WHERE Bedingung zu verwenden.
B Beispiel. Zeige für jedes Land die Anzahl der Lieferanten mit einer Bewertung D. Auch Länder ohne
entsprechende Lieferanten sollen ageführt werden.
2
SELECT S_Country , COUNT ( IF ( S_Evaluation = ’D ’ , ’D ’ , NULL )) FROM Supplier
GROUP BY 1
Mithilfe des IF wird ein Ausdruck analog zur S Website-Spalte im ersten Beispiel erzeugt: Für Lieferanten mit Bewertung 6= D ist dieser Ausdruck NULL, ansonsten 6=NULL.
• Left und Right Joins mit zusätzlichen Bedingungen •
Bisher wurden Bedingungen den Join betreffend immer ins ON geschrieben, alle anderen Bedingungen
ins WHERE. Bei Left bzw. Right Joins kann es notwendig sein, Bedingungen ins ON zu geben.
B Beispiel. Zeige für alle italienischen Lieferanten, welche Teile sie anbieten. Ergänze diese Tabelle um
alle nicht-italienischen Lieferanten (mit NULL in der Spalte für die angebotenen Teile).
3
SELECT S_Company , P_No FROM Order_Options o RIGHT JOIN Supplier s
ON s . S_No = o . S_No
AND S_Country = ’ Italien ’
Offenbar ist ein Right (oder Left) Join nötig. Allerdings ist es hier wichtig, dass die Bedingung an das
Land im ON steht. Andernfalls, mit der Bedingung im WHERE, wird diese erst nach dem Join (und dem
entsprechenden ON) überprüft, sodass die nicht-italienischen (wie alle anderen) Lieferanten zwar nach
dem Right Join berücksichtigt werden, durch die WHERE Bedingung aber wieder rausfallen.
SS 2016
Damit bekommen wir auch eine alternative Lösung für unser COUNT Problem von vorhin.
B Beispiel. Zeige für jedes Teil die Anzahl der italienischen Lieferanten, die das Teil anbieten. Führe
auch jene Teile an, die von keinem italienischen Lieferanten angeboten werden.
2
SELECT P_No , COUNT ( DISTINCT S_Company )
FROM Order_Options o LEFT JOIN Supplier s
ON s . S_No = o . S_No
AND S_Country = ’ Italien ’
GROUP BY 1
Das DISTINCT garantiert, dass Lieferanten nicht mehr als einmal gezählt werden. Die andere Lösung
mit IF würde folgendermaßen aussehen.
SELECT P_No , COUNT ( DISTINCT IF ( S_Country = ’ Italien ’ , S_Company , NULL ))
FROM Order_Options o JOIN Supplier s
ON s . S_No = o . S_No
GROUP BY 1
Man beachte, dass hier kein Left Join nötig ist.
• Left und Right Joins mit mehr als zwei Tabellen • funktionieren wie mit zwei Tabellen, allerdings müssen Klammern verwendet werden, um die Abarbeitungsreihenfolge festzulegen.
B Beispiel. Zeige alle Teile zusammen mit den sie anbietenden Lieferanten. Führe auch Teile an, die
von keinem Lieferanten angeboten werden.
1
SELECT P_Text , S_Company
FROM ( Supplier s JOIN Order_Options o ) RIGHT JOIN Parts p
ON p . P_No = o . P_No AND s . S_No = o . S_No
In einigen Fällen kann es notwendig sein, folgende alternative Notation zu verwenden, in der nach jedem
Join jeweils das entsprechende ON angeführt wird.
B Beispiel. Zeige alle Teile zusammen mit den sie anbietenden Lieferanten.
2
SELECT P_Text , S_Company
FROM Supplier s JOIN ( Order_Options o RIGHT JOIN Parts p
ON p . P_No = o . P_No )
ON s . S_No = o . S_No
Man beachte, dass diese Abfrage keine Teile anzeigt, die von keinem Lieferanten angeboten werden.
Diese werden zwar durch den Right Join vorübergehend berücksichtigt, durch den Join auf die Tabelle
Supplier fallen sie allerdings wieder raus (da in der Spalte S No in den entsprechenden Zeilen nach
dem Right Join NULL steht). Ersetzt man den allerdings den ersten Join ebenfalls durch einen Right
Join, so werden auch Teile angezeigt, die von keinem Lieferanten angeboten werden.
Zeige alle Teile zusammen mit den sie anbietenden Lieferanten. Führe auch Teile an, die von keinem
Lieferanten angeboten werden.
1
SELECT P_Text , S_Company
FROM Supplier s RIGHT JOIN ( Order_Options o RIGHT JOIN Parts p
ON p . P_No = o . P_No )
ON s . S_No = o . S_No
Herunterladen