Unterabfragen als Spalten
Eine Unterabfrage kann auch eine Spalte des Ergebnisses sein. Wie viele Bewertungen hat jedes Spiel?
SELECT s.titel,
(SELECT COUNT(*) FROM bewertungen AS bw WHERE bw.spiel_id = s.id) AS anzahl_bewertungen
FROM spiele AS s
ORDER BY anzahl_bewertungen DESC, s.titel;| titel | anzahl_bewertungen |
|---|---|
| Dragon Forge | 4 |
| Cube Logic | 2 |
| Knight's Oath | 2 |
| Moon Farm | 2 |
| … | … |
Die Unterabfrage ist korreliert, wie die mit EXISTS: Sie bezieht sich auf s.id, das Spiel der äußeren Zeile. Für jedes Spiel zählt die Datenbank die Bewertungen mit der ID dieses Spiels, und die Zahl kommt in die Spalte anzahl_bewertungen. Castle Siege und die anderen Spiele ohne Bewertung bekommen 0, denn COUNT(*) von keinen Zeilen ist 0.
Eine Unterabfrage in SELECT muss für jede Zeile einen Wert liefern: Sie muss eine Spalte liefern und sollte höchstens eine Zeile finden (bei mehreren würde SQLite stillschweigend die erste nehmen), also ist sie meist ein Aggregat. Wenn sie gar keine Zeile findet, ist der Wert NULL. Und gib der Spalte einen Alias, sonst heißt sie wie der ganze Text der Unterabfrage.
Du kennst eine andere Art zu zählen: LEFT JOIN mit GROUP BY und COUNT(bw.sterne), aus der Lektion über Joins. Beide geben dasselbe Ergebnis. Eine Unterabfrage ist praktisch, wenn du mehrere Zahlen aus verschiedenen Tabellen brauchst: Jede Unterabfrage zählt für sich, also vervielfachen sich keine Zeilen, wie es passiert, wenn du bewertungen und positionen gleichzeitig mit den Spielen verbindest (eine der Stolperfallen bei Joins aus der Lektion über Joins).
Typischer Fehler: die Bedingung vergessen, die die Unterabfrage mit der Zeile verbindet. (SELECT COUNT(*) FROM bewertungen) zählt alle Bewertungen der Tabelle, also würde jedes Spiel 25 zeigen.
So schreibst du es:
Anweisungen
- 1
Zeige für jeden Kunden den Namen und das Datum seiner letzten Bestellung als
letzte_bestellung. Benutze eine Unterabfrage inSELECT, die das spätestebestellt_amder Bestellungen des Kunden findet. Sortiere nach dem Namen:name letzte_bestellung Anna Fischer 2025-04-15 Emma Becker 2025-11-14 Greta Hoffmann 2025-09-27 Hannes Schulz NULL … … - 2
Hannes Schulz und Max Krause haben noch nie etwas bestellt, also ist ihre
letzte_bestellungNULL. Zeige stattdessen den Textnie: Setze die ganze Unterabfrage inCOALESCE(). Das Ergebnis beginnt dann so:name letzte_bestellung Anna Fischer 2025-04-15 Emma Becker 2025-11-14 Greta Hoffmann 2025-09-27 Hannes Schulz nie … … - 3
Zeige darunter für jedes Spiel seinen Titel, die Anzahl der Exemplare, die Kunden bestellt haben, als
exemplare(die Summe vonmengeinpositionen) und seine durchschnittlichen Sterne, auf eine Nachkommastelle gerundet, alswertung. Du brauchst zwei Unterabfragen. Sortiere nach dem Titel:titel exemplare wertung Bakery Story 3 4.0 Castle Siege 1 NULL Cube Logic 3 4.0 Dragon Forge 4 4.3 … … …