Q2 Datenbanken

SQL Lektion 5: Unterabfragen

Lösung geprüft

Die Aufgabe der heutigen Stunde ist die fünfte SQL-Lektion: geschachtelte Abfragen. In den Zusatzaufgaben davor haben wir sie schon benutzt, jetzt schauen wir sie uns richtig an. Eine Unterabfrage ist einfach ein SELECT in Klammern innerhalb eines anderen SELECT.

Die Aufgabenstellung lautet

a) Bearbeiten Sie die fünfte Lektion und erstellen Sie in ihrem OneNote-Heft eine kompakte übersichtliche Kurzzusammenfassung der SQL-Befehle.
b) Bearbeiten Sie die Übung 5

Zusatzaufgabe: Gib alle Regionen und deren durchschnittliches BIP an, deren durchschnittliches BIP über dem BIP-Gesamtdurchschnitt liegt.

Teil b) der Aufgabe – Bearbeiten Sie die Übung 5 – liegt auf der Tutorial-Seite und ist im OneNote nicht abgedruckt. Hier stehen die Zusammenfassung und die Zusatzaufgabe.

Die zwei Sorten von Unterabfragen

SQL
/* meininfokurs.cmrg.site */
-- Zusammenfassung der fuenften SQL-Lektion: Unterabfragen
-- @meininfokurs.cmrg.site

-- Sorte 1: Die Unterabfrage liefert EINEN Wert -> Vergleich mit = < >
SELECT Fahrerweltmeister, WM_Punkte
FROM   WMTitel
WHERE  WM_Punkte > (SELECT AVG(WM_Punkte) FROM WMTitel);


-- Sorte 2: Die Unterabfrage liefert MEHRERE Werte -> Vergleich mit IN
SELECT Saison, Fahrerweltmeister
FROM   WMTitel
WHERE  Fahrerweltmeister IN (SELECT Fahrerweltmeister
                             FROM   WMTitel
                             WHERE  WM_Punkte > 100);
Unterabfrage liefertPassender Operator
genau einen Wert= < > <= >= <>
mehrere WerteIN oder NOT IN

Das ist die häufigste Fehlerquelle: benutzt man = und die Unterabfrage liefert mehr als eine Zeile, bricht die Datenbank mit Subquery returns more than 1 row ab. Dann muss man entweder auf IN wechseln oder die Unterabfrage so bauen, dass sie wirklich nur einen Wert liefert – zum Beispiel mit einer Aggregatfunktion.

Wann Unterabfrage, wann JOIN?

Vieles geht mit beidem. Die Faustregel:

Du willstNimm
Spalten aus zwei Tabellen anzeigenJOIN
Nur filtern, ohne die zweite Tabelle anzuzeigenUnterabfrage
Mit einem berechneten Wert vergleichen (Durchschnitt, Maximum)Unterabfrage – mit JOIN geht das nicht

Der dritte Fall ist der, für den es keine Alternative gibt, und genau der kommt in der Zusatzaufgabe vor.

Die Zusatzaufgabe

Die Tabelle cia ist im OneNote nicht abgedruckt. Ich schreibe gegen die Spalten region und bip – Namen gegebenenfalls anpassen.
SELECT   region, AVG(bip) AS DurchschnittBIP
FROM     cia
GROUP BY region
HAVING   AVG(bip) > (SELECT AVG(bip) FROM cia)
ORDER BY DurchschnittBIP DESC;

Zwei Durchschnitte, die verschieden sind

Der Kern der Aufgabe ist, dass hier zwei verschiedene Durchschnitte vorkommen und man sie nicht verwechseln darf:

WoWas gerechnet wird
AVG(bip) im SELECT und HAVINGDurchschnitt innerhalb einer Region, weil GROUP BY aktiv ist
(SELECT AVG(bip) FROM cia)Durchschnitt über alle Länder, unabhängig von der Gruppierung

Zweimal derselbe Text AVG(bip), und trotzdem zwei völlig verschiedene Zahlen – der Unterschied entsteht nur dadurch, dass die Unterabfrage ihr eigenes FROM cia hat und vom GROUP BY außen nichts mitbekommt.

Und es muss HAVING sein, nicht WHERE: der Regionsdurchschnitt existiert erst, nachdem gruppiert wurde. In WHERE könnte man ihn gar nicht ansprechen.

Wie die Datenbank das abarbeitet

  1. Die Unterabfrage läuft einmal und liefert eine feste Zahl, zum Beispiel 18 500
  2. Die äußere Abfrage gruppiert alle Länder nach Region
  3. Für jede Region wird der Durchschnitt gebildet
  4. HAVING wirft alle Regionen raus, deren Durchschnitt unter 18 500 liegt
  5. ORDER BY sortiert die übrigen

Wichtig ist Schritt 1: die Unterabfrage hängt von nichts ab, was außen passiert, also muss sie nur ein einziges Mal ausgeführt werden. Solche Unterabfragen nennt man unkorreliert, und sie sind schnell. Es gibt auch korrelierte, die für jede Zeile neu laufen – die braucht man im Grundkurs aber nicht.

Aufgabe suchen

Tippe los. Strg+K öffnet die Suche von überall.

Zuletzt angesehen

Werbung