Anfragetypen in SQL zwei Typen von SQL-Ausdrücken: Resultat: abgeleitete Tabelle ( derived table ) Tabellenausdrücke DB Bedingungen Problem (?): Nur Tabellenausdrücke dürfen direkt vom Benutzer als Anfrage gestellt werden (à la Auswahlabfragen in Access)! ja nein Resultat: Wahrheitswert 2002 Prof. Dr. Rainer Manthey Informationssysteme 1 Zusammenfassung Tabellenausdrücke bisher: vorwiegend Tabellenausdrücke ("eigentliche Anfragen") betrachtet Zusammenfassung der kennengelernten syntaktischen Möglichkeiten: SELECT-Ausdrücke: Format: SELECT-FROM-WHERE (π,, σ) Tupelvariablen zur Umbenennung und als Spaltenpräfix Umbenennung durch AS JOIN-Operatoren im FROM-Teil (JOIN, NATURAL JOIN) Unteranfragen im FROM- und WHERE-Teil IN-Operator im WHERE-Teil TABLE-Operator zum direkten Zugriff auf Tabellen komplexe Anfragen durch Algebra-Operatoren: UNION, INTERSECT, MINUS 2002 Prof. Dr. Rainer Manthey Informationssysteme 2
Bedingungen: Übersicht zweite grosse Klassen von SQL-Ausdrücken: Bedingungen (engl.: "conditional expressions") Bedingungen sind Boolesche Ausdrücke, die entweder wahr oder falsch sind. Vorkommen von Bedingungen vor allem als Auswahlkriterium im WHERE-Teil von SELECT-Ausdrücken als Integritätsbedingungen in CHECK-Klauseln zwei fundamentale Formen von Bedingungen, die nicht anderweitig ausdrückbar sind: Vergleichsbedingungen Existenzbedingungen Zusammengesetzte Bedingungen: mittels Boolescher Operatoren AND, OR, NOT aus einfacheren Bedingungen komponierbar diverse spezielle Formen von Bedingungen: auf Vergleichs- oder Existenzgungen äquivalent zurückführbar (und daher eigentlich verzichtbar) 2002 Prof. Dr. Rainer Manthey Informationssysteme 3 Vergleichsbedingungen Vergleichsbedingungen dienen dem Vergleich von Spaltenwerten einzelner Zeilen mit konstanten Werten oder mit Werten in anderen Spalten mittels der folgenden acht Vergleichsoperatoren: = <> < > =< >= Operanden elementarer Vergleiche können auch durch Unteranfragen berechnet werden (sofern die Antwortmenge dann einelementig ist): einfach: z.b. P.alter = 30 oder P.alter > Q.alter komplex: z.b. X.alter > ( SELECT Y.alter FROM person Y WHERE Y.name = John ) weitere spezielle Operatoren in elementaren Vergleichen in Standard-SQL: X.name LIKE Man% (%: wildcard ) ("pattern matching"-operator: nicht anderweitig ausdrückbar) X.alter BETWEEN 40 AND 50 (Intervalloperator; alternativ mittels '=<' und '>=' ausdrückbar) 2002 Prof. Dr. Rainer Manthey Informationssysteme 4
Existenzbedingungen Existenzbedingungen testen, ob die Antworttabelle einer Unteranfrage leer ist oder nicht, z.b.: Welche Städte liegen an einem Fluss? SELECT Name FROM stadt WHERE EXISTS ( SELECT Fluss FROM stadt_an_fluss WHERE Stadt = Name ) Existenzbedingungen können auch negiert werden: NOT EXISTS Positive Existenzbedingungen sind durch Entschachteln und Produkt- oder Joinbildung auch ohne expliziten Quantor ausdrückbar (und damit im Kontext von SELECT-Ausdrücken an sich überflüssig), z.b.: Ist nötig, weil EXISTS Duplikate eliminiert! SELECT DISTINCT Name FROM stadt, stadt_an_fluss WHERE Stadt = Name ) 2002 Prof. Dr. Rainer Manthey Informationssysteme 5 Existenzbedingungen (2) In Integritätsbedingungen (ohne umschliessendes SELECT!) sind EXISTS-Ausdrücke aber ein zentrales Ausdrucksmittel (Details später in 3.3), z.b. CHECK EXISTS (SELECT * FROM stadt_an_fluss WHERE Stadt = 'Bonn') Negative Existenzbedingungen lassen sich nur mittels NOT EXISTS ausdrücken, aber nicht durch entschachteln. (Es gibt kein "negatives Produkt"!) Welche Städte liegen an keinem Fluss? SELECT Name FROM stadt WHERE NOT EXISTS ( SELECT Fluss FROM stadt_an_fluss WHERE Stadt = Name ) Access-SQL kennt kein explizites NOT EXISTS, sondern drückt diese Form der Bedingungen durch einen Booleschen Vergleich aus: WHERE ( EXISTS ( SELECT Fluss FROM stadt_an_fluss WHERE Stadt = Name ) = False ) 2002 Prof. Dr. Rainer Manthey Informationssysteme 6
Existenzbedingungen (3) Auch Inklusionsausdrücke (IN, NOT IN) lassen sich auf Existenzbedingungen durch äquivalente Umformung zurückführen, obwohl sie syntaktisch eigentlich eher in die Klasse der Vergleichsbedingungen gehören, z.b.: SELECT * FROM stadt WHERE Name NOT IN ( SELECT Name FROM großstadt ) ; Syntaktisch weniger aufwändig! SELECT * FROM stadt AS S WHERE NOT EXISTS ( SELECT * FROM großstadt AS G WHERE S.Name = G.Name ) ; 2002 Prof. Dr. Rainer Manthey Informationssysteme 7 Simulation von Allquantoren durch EXISTS SQL kennt allerdings kein Schlüsselwort für den Allquantor (kein 'FORALL'!). Universelle Bedingungen müssen durch logische Umformung und Rückführung auf den Existenzquantor mittels doppelter Negation sozusagen "simuliert" werden. Zugrundeliegende Umformungsregel der Prädikatenlogik: x: F x: F Beispiel: "Welcher Fluss fließt durch alle Bundesländer?" ( SELECT F.Name FROM fluss AS F WHERE NOT EXISTS ( SELECT * FROM land AS L WHERE L.Name NOT IN ( SELECT Land FROM fluss_durch_land WHERE Fluss = F.name ) 2002 Prof. Dr. Rainer Manthey Informationssysteme 8
Quantoren in Vergleichsbedingungen SQL kennt einen zweiten "Satz" an Quantoren, die aber nur in komplexen Vergleichsbedingungen vorkommen dürfen: ANY, SOME, ALL Diese Quantoren ermöglichen es, simultan Vergleiche mit den Elementen einer Antworttabelle auf eine Unteranfrage durchzuführen ("deklarative Schleife"). Beispiel: Welche Stadt in NRW hat mehr Einwohner als jede andere Stadt in diesem Bundesland? SELECT Name FROM stadt_in_nrw AS X WHERE X.Einwohner > ALL (SELECT Y.Einwohner FROM stadt_in_nrw AS Y WHERE Y.Name <> X.Name) ANY und SOME sind Synonyme (aus sprachlichen Gründen ist mal das eine, mal das andere Wort im Englischen passender); > ANY bedeutet "größer als irgendein". 2002 Prof. Dr. Rainer Manthey Informationssysteme 9 Quantoren in Vergleichsbedingungen (2) Auch diese syntaktische Variante ist wiederum nur aus Gründen des größeren syntaktischen Komforts in bestimmten Situationen eingeführt worden. Sie lässt sich systematisch auf Existenzbedingungen zurückführen und ist somit redundant, z.b.: SELECT Name FROM stadt_in_nrw AS X WHERE X.Einwohner > ALL (SELECT Y.Einwohner FROM stadt_in_nrw AS Y WHERE Y.Name <> X.Name) SELECT Name FROM stadt_in_nrw AS X WHERE NOT EXISTS (SELECT * FROM stadt_in_nrw AS Y WHERE Y.Name <> X.Name AND NOT (X.Einwohner > Y.Einwohner) ) 2002 Prof. Dr. Rainer Manthey Informationssysteme 10
Test auf eindeutige Existenz in SQL Mit den bisher eingeführten syntaktischen Mitteln ist es ziemlich unkomfortabel, zu überprüfen, ob genau ein Objekt mit einer bestimmten Eigenschaft existiert. Beispiel: Welche Städte liegen an genau einem Fluss? SELECT S.Name FROM stadt AS S WHERE EXISTS (SELECT * FROM stadt_an_fluss AS X WHERE X.Stadt = S.Name AND NOT EXISTS (SELECT * FROM stadt_an_fluss AS Y WHERE Y.Stadt = X.Stadt AND NOT (Y.Fluss = X.Fluss)) Nicht vergessen! Prädikatenlogischer Hintergrund: Der!-Operator wird "simuliert" mittels! x: F x: F [ y: F (y=x) ] bzw.... x: F [ y: F (y=x) ] 2002 Prof. Dr. Rainer Manthey Informationssysteme 11 Test auf eindeutige Existenz in SQL (2) Zum Glück hat SQL eine "Spezialsyntax" für diese gar nicht so seltene Formulierung "genau ein" parat! Das Schlüsselwort UNIQUE kann auch zum Bilden einer speziellen Form von Bedingung verwendet werden, mit der man Überprüfen kann, ob eine Antworttabelle duplikatfrei ist, z.b.: UNIQUE (SELECT Kurzform FROM land) Damit kann man zumindest den zweiten Teil der Eindeutigkeitsbedingung etwas verkürzen - viel macht das aber noch nicht aus: SELECT FROM WHERE S.Name stadt AS S EXISTS (SELECT * FROM stadt_an_fluss AS X WHERE X.Stadt = S.Name AND UNIQUE (SELECT * FROM stadt_an_fluss AS Y WHERE Y.Fluss = X.Fluss) 2002 Prof. Dr. Rainer Manthey Informationssysteme 12
Test auf eindeutige Existenz in SQL (3) Aber wenn man noch etwas tiefer in den SQL-Büchern stöbert, findet man noch weitere "obskure" Spezialoperatoren, die einem aber entscheidend weiter helfen: X.name MATCH (SELECT Y.name FROM..... ) entspricht: X.name = SOME.... X.name MATCH UNIQUE ( SELECT Y.name FROM.... ) entspricht: Es existiert genau ein Y.Name... Damit lässt sich die Frage nach den Städten, die an genau einem Fluss liegen, dann endlich halbwegs "menschlich" ausdrücken: SELECT FROM WHERE S.Name stadt AS S S.Name MATCH UNIQUE (SELECT Stadt FROM stadt_an_fluss); Leider kennt Access-SQL all diese schönen Erleichterungen nicht, die der Standard bereit hält! MATCH und UNIQUE sind unbekannt, SOME und ALL gibt es aber. 2002 Prof. Dr. Rainer Manthey Informationssysteme 13 Existenzbedingungen: Resümee Warum diese ganze "Wirbelei" mit Quantoren in SQL???? Nur sehr einfache Anfragen lassen sich ohne die genauere Kenntnis von Existenzbedingungen formulieren. Sowie das Wörtchen "alle" bzw. "jeder" ins Spiel kommt, wird es schwierig und Quantoren sind unvermeidbar! Auch "genau ein"-anfragen haben es in sich, sind aber in der Praxis nicht gerade selten. Der QBE-Stil von Access lässt einen bei diesen Anfragetypen "im Regen stehen": Ohne SQL-Formulierung geht's nicht! Ohne gute Grundkenntnisse der Prädikatenlogik (insbesondere der Quantoren) kann man niemals vernünftig SQL anwenden! 2002 Prof. Dr. Rainer Manthey Informationssysteme 14
Aggregatfunktionen wichtige Klasse von built-in -Funktionen in SQL: Aggregatfunktionen COUNT SUM AVG MAX MIN Anzahl Summe Durchschnitt (engl.: "average") Maximum Minimum Berechnen einen skalaren Wert aus einer Menge von skalaren Werten ( Aggregat ), die aus einer Spalte einer Tabelle stammen: Tabelle Aggregat Funktionswert 2002 Prof. Dr. Rainer Manthey Informationssysteme 15 Aggregatfunktionen (3) Beispiele von Aggregatausdrücken im SELECT-Teil: Berechne das Gesamtgehalt aller C3-Professoren! SELECT SUM ( P.Gehalt ) AS Total FROM professoren AS P WHERE P.Grad = C3 ratsam, um Spaltennamen in der Antworttabelle zu haben Welche C3-Professoren sind älter als alle C4-Professoren? SELECT FROM WHERE P.Name professoren AS P P.Grad = C3 AND P.Alter > ( SELECT MAX (Q.Alter) FROM professoren AS Q WHERE Q.Grad = C4 ) 2002 Prof. Dr. Rainer Manthey Informationssysteme 16
Aggregatfunktionen (4) oft verwendet im Zusammenhang mit Aggregatfunktionen: erweiterte SELECT-Blöcke mit Unterteilung der Resultattabelle in Gruppen dazu vorgesehen: GROUP BY- und (ggf.) HAVING-Teile in SELECT-Blöcken Grundidee: Resultat der Auswertung von SELECT-FROM-WHERE (Tabelle) unterteilt in Untertabellen (Gruppen) mit identischen Werten für bestimmte Gruppierungsspalten (festgelegt im GROUP BY-Teil) optional: Gruppen, die bestimmte Bedingung nicht erfüllen (HAVING-Teil), werden eliminiert. Aggregatfunktionen werden auf Gruppen (als Aggregate) angewendet, wenn GROUP BY spezifiziert ist: z.b.: SELECT FROM GROUP BY HAVING P.Grad, AVG( P.alter ) AS AvgAlter professoren AS P P.Grad P.Grad > C2 2002 Prof. Dr. Rainer Manthey Informationssysteme 17 Aggregatfunktionen (5) Illustration mit Beispieldaten: SELECT FROM GROUP BY HAVING P.Grad, AVG( P.alter ) AS Avgalter professoren AS P P.Grad P.Grad > C2 GROUP BY Name Grad Alter Jim C4 43 John C3 33 Ken C4 57 Lisa C4 39 Tom C2 32 Eva C3 36 Name Grad Alter Jim C4 43 Ken C4 57 Lisa C4 39 John C3 33 Eva C3 36 Tom C2 32 AVG Grad Avgalter C3 34.5 C4 46.3 HAVING 2002 Prof. Dr. Rainer Manthey Informationssysteme 18
Aggregatfunktionen (6) Auch das GROUP BY-Konstrukt ist eigentlich redundant: SELECT P.Grad, MAX (P.Alter) AS X, MIN (P.Alter) AS Y FROM professoren AS P WHERE P.Grad > C2 GROUP BY P.Grad Äquivalente Formulierung ohne Verwendung von GROUP BY: SELECT DISTINCT P.Grad, ( SELECT MAX (P.Alter) FROM professoren AS P1 WHERE P.Grad = P1.Grad) AS X, ( SELECT MIN (P.Alter) FROM professoren AS P2 WHERE P.Grad = P2.Grad) AS Y FROM professoren AS P WHERE P.Grad > C2 2002 Prof. Dr. Rainer Manthey Informationssysteme 19 Aggregatfunktionen (7) auch HAVING-Teil ist im Prinzip überflüssig (aber oft komfortabler): Welche Vorlesungen werden von mehr als einem Professor angeboten? SELECT V.Titel FROM vorlesungen V GROUP BY V.Titel HAVING COUNT(*) > 1 äquivalent ohne GROUP BY und HAVING: SELECT DISTINCT V.Titel FROM vorlesungen V WHERE ( SELECT COUNT(*) FROM vorlesungen V1 WHERE V.Titel = V1.Titel ) > 1 2002 Prof. Dr. Rainer Manthey Informationssysteme 20
Nullwerte SQL bietet vordefinierten, universellen Nullwert NULL an, um fehlende Informationen einheitlich zu repräsentieren. Die korrekte Verwendung von NULL bereitet zahlreiche Schwierigkeiten (zum Teil auch wegen inkonsequenter Entwurfsentscheidungen in SQL). Nullwerte können sehr unterschiedliche interpretiert werden. Mögliche Interpretationen: Wert existiert, ist aber zur Zeit unbekannt. Es ist bekannt, dass in dieser Zeile kein Wert in der fraglichen Spalte existiert. Es ist nicht bekannt, ob ein Wert existiert bzw. wenn ja, wie er lautet. intendierte Interpretation von NULL in SQL: Wert existiert, ist aber unbekannt daher: NULL wird auch als Wert bezeichnet! Je zwei Vorkommen von NULL repräsentieren verschiedene "echte" Werte, die eben (noch) unbekannt sind. * allerdings: NULL selbst hat keinen Typ, übernimmt stets den Typ der jew. Spalte. 2002 Prof. Dr. Rainer Manthey Informationssysteme 21 Nullwerte (2) NULL darf in vielen Fällen aber nicht wie ein Wert genutzt werden, z.b. NULL darf nicht als Operand einer Funktion auftreten (z.b.: X+NULL) NULL darf nicht in Vergleichsbedingungen stehen (z.b.: X=NULL) Zum Testen, ob eine Spalte NULL enthält, gibt es eine spezielle Syntax: X IS NULL X IS NOT NULL Liefert die Auswertung eines Teilausdrucks NULL als Resultat, dann liefert der Gesamtausdruck ebenfalls NULL als Ergebnis, z.b.: person Name Alter Jim 33 Tom NULL SELECT (65 - Alter) AS Rest FROM person WHERE Name = Tom NULL 2002 Prof. Dr. Rainer Manthey Informationssysteme 22
Nullwerte (3) Ausnahme: Aggregatfunktionen (bis auf COUNT) ignorieren NULL! person Name Alter Jim 33 Tom NULL SUM (alter): 33 AVG (alter): 16.5 COUNT(alter): 2 AVG = SUM/COUNT In Vergleichen (und anderen Bedingungen) führt NULL zur Verwendung einer dreiwertigen Logik, d.h. einer Logik mit drei statt zwei Wahrheitswerten: TRUE FALSE UNKNOWN * Beispiel: Wenn A=3, B=4 und C=NULL sind, dann ist etwa A > B AND B > C: FALSE A > B OR B > C: UNKNOWN 2002 Prof. Dr. Rainer Manthey Informationssysteme 23 Nullwerte (4) Wahrheitstafeln der Booleschen Operatoren in dreiwertiger Logik: AND T U F OR T U F NOT T T U F U U U F F F F F T U F T T T T U U T U F T U F F U T Berücksichtigung von NULL bei der Auswertung von SELECT-Ausdrücken: Alle FROM-Zeilen werden eliminiert, für die der WHERE- Teil nicht TRUE als Ergebnis liefert. folglich: Eine Zeile wird eliminiert, wenn der WHERE-Teil FALSE oder UNKNOWN liefert!! 2002 Prof. Dr. Rainer Manthey Informationssysteme 24
Nullwerte (5) spezielle Syntax für das Testen des Wahrheitswerts einer Bedingung: <conditional-expression> IS [ NOT ] { TRUE UNKNOWN FALSE } Bedeutung solcher IS-Ausdrücke: TRUE genau dann, wenn die Auswertung der linken Seite den Wahrheitswert auf der rechten Seite liefert; FALSE sonst. Konsequenz: p IS NOT TRUE ist nicht mehr äquivalent mit NOT p! (wenn p UNKNOWN, liefert NOT p ebenfalls UNKNOWN) weitere logische Falle : EXISTS verhält sich nicht wie ein Existenzquantor in dreiwertiger Logik EXISTS ( <table-expression>) liefert FALSE, wenn <table expression> eine leere Tabelle liefert, ansonsten TRUE -- aber niemals UNKNOWN! Kapitel 16 im Buch von Date schliesst mit folgendem Abschnitt: 16.6 A RECOMMENDATION Avoid nulls. 2002 Prof. Dr. Rainer Manthey Informationssysteme 25