Hinweis . . . | |
Unterabfragen (subqueries) | |
Virtuelle Spalten: AS | |
Logik | |
Berechnungen: Aggregatfunktionen in SQL | |
GROUP BY & HAVING | |
Views (Sichten) | |
Beispiel | |
Aufgaben | |
Diesen Hinweis entnehmen wir einer guten Einführung in unser Thema:
Abfragen erstellen "keine neuen Daten. Vielmehr sind die berechneten Werte temporär. Sie werden bei jeder Durchführung einer Abfrage neu berechnet." |
(aus: H. Eirund/U. Kohl: Datenbanken - leicht gemacht, Stuttgart, Leipzig: B. G. Teubner, 2000, S. 88)
<<<Unterabfragen (subqueries) sind verschachtelte SQL-Abfragen, Beispiel:
SELECT name, lehrernr FROM sar_lehrer WHERE vorname IN ( SELECT vorname FROM sar_lehrer WHERE vorname = 'Walter' );
Wirkung:
name | lehrernr ===================== Spiegel | 1
Wie funktionieren Unterabfragen? Die innere Abfrage liefert eine Menge von Datensätzen zurück (Selektion!), auf der dann die äußere Abfrage arbeitet. Der Operator IN
vergleicht Spaltenwerte aus der Spalte vorname
mit jedem Element aus der inneren Abfrage.
Man beachte, dass die Abfrage oben kein sinnvolles Beispiel für Unterabfragen ist . . .
Man kann in SQL virtuelle Spalten beziehungsweise Tabellen einführen über den Zusatz AS, virtuell, da die Tabellen/Spalten nur für diese Abfrage zur Verfügung stehen. Gerne wird ein Alias auch als Abkürzung für einen Tabellennamen benutzt wie im folgenden Beispiel:
SELECT name, thema FROM sar_lehrer AS l, sar_projekt AS p WHERE l.prowonr = p.prowonr;
In der folgenden Abfrage wird eine virtuelle Spalte eingeführt, ein sinnvolleres Beispiel wäre die Multiplikation mit dem Mehrwertsteuersatz.
SELECT name,thema, anzahl * lehrernr AS unsinn FROM sar_lehrer AS l, sar_projekt AS p WHERE l.prowonr = p.prowonr;<<<
Beim Join kann man die Bedingung durch logische Operatoren wie AND, OR oder NOT "verfeinern":
SELECT name, klasse, thema FROM sar_wahl AS w, sar_projekt AS p, sar_schueler AS s WHERE w.prowonr = p.prowonr AND w.schuelernr = s.schuelernr ORDER BY klasse, name;
Das Ergebnis ist wirklich grossartig, die
Idee zu dieser Abfrage stammt NICHT von mir . . .
Frage: Nach welcher Information wird hier gefragt?
Man will gelegentlich Berechnungen über alle Datensätze durchführen, die eine bestimmte Bedingung erfüllen, zum Beispiel Minimum oder Maximum-Bestimmung. In SQL benutzt man an dieser Stelle sogenannte Aggregatfunktionen.
SELECT count(name) FROM sar_wahl AS w, sar_projekt AS p, sar_schueler AS s WHERE w.prowonr = p.prowonr AND w.schuelernr = s.schuelernr AND p.thema = 'Easy-Webdesign';
Ergebnis:
count(name) ============= 10
Frage: Nach welcher Information wird hier gefragt?
Weitere Aggregatfunktionen:
Abfragen geben Datensätze ungeordnet zurück, wenn ich aber beispielsweise wissen möchte, wieviel Schüler ein bestimmtes Projekt gewählt haben, muss ich die Datensätze irgendwie gruppieren, für die Gruppenbildung entscheidend sind hierbei gleiche Werte in einer bestimmten Spalte, Beispiel:
SELECT thema, count(*) FROM sar_wahl AS w, sar_projekt AS p, sar_schueler AS s WHERE w.prowonr = p.prowonr AND w.schuelernr = s.schuelernr GROUP BY thema;
Ergebnis:
thema | count(*) ================================= Easy-Webdesign | 9.0 HTML für Einsteiger | 7.0 So ein Theater | 8.0
Die Bedingung unter WHERE sucht die Schülerwahlen aus, dann wird nach dem gewählten Projekt gruppiert und die Anzahl der Schülerwahlen summiert. Man kann die Gruppenbildung kombinieren mit einer "Selektion" über den HAVING-Befehl:
SELECT thema, count(*) FROM sar_wahl AS w, sar_projekt AS p, sar_schueler AS s WHERE w.prowonr = p.prowonr AND w.schuelernr = s.schuelernr GROUP BY thema HAVING count(*) < 9;
Ergebnis:
thema | count(*) ================================= HTML für Einsteiger | 7.0 So ein Theater | 8.0
Über den BETWEEN
-Operator kann man auch ein Intervall angeben:
SELECT thema, count(*) FROM sar_wahl AS w, sar_projekt AS p, sar_schueler AS s WHERE w.prowonr = p.prowonr AND w.schuelernr = s.schuelernr GROUP BY thema HAVING count(*) BETWEEN 4 AND 7;
Ergebnis:
thema | count(*) ================================= HTML für Einsteiger | 7.0<<<
Manchmal ist in SQL eine eingeschränkte Sicht auf die Daten notwendig, sei es aus datenschutzrechtlichen Gründen oder aus eher praktischen Erwägungen, in SQL kann man an dieser Stelle Views (Sichten) benutzen:
CREATE VIEW prowo AS SELECT prowonr, thema, anzahl FROM sar_projekt;
Ergebnis ist eine Projekt-Tabelle mit drei Spalten, wie man der Abfrage SELECT * FROM prowo;
entnimmt.
PS: Views lassen sich mit dem DROP-Befehl wieder löschen: DROP VIEW prowo;
sie verhalten sich also genauso wie Tabellen. Was aber passiert beim Einfügen neuer Datensätzte mittels INSERT? (Aufgabe!)
Siehe die Datei "beispiel_sql_03.txt" in der Zip-Datei prowo.zip (in gfsqlite als SQL-Datei einlesen, davor die prowo-Datenbank öffnen), vergleiche auch im Datenbanken-Reader S. 93-96 (Abschnitt 5.1 & 5.2).
<<<AND, OR, NOT
aus.