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