WHERE und HAVING zusammen
Eine Abfrage kann sowohl WHERE als auch HAVING haben, und jedes hat seine eigene Aufgabe. WHERE filtert Zeilen, bevor sie gruppiert werden: Die Zeilen, die seine Bedingung nicht erfüllen, kommen in keine Gruppe. HAVING filtert Gruppen, nachdem sie gebildet und gezählt wurden.
Welche Genres haben mindestens 3 Spiele, die schon erschienen sind? Ob ein Spiel erschienen ist, ist eine Frage zu einer Zeile, also gehört sie in WHERE. „Mindestens 3“ betrifft eine ganze Gruppe, also gehört es in HAVING:
SELECT genre, COUNT(*) AS erschienene_spiele
FROM spiele
WHERE erschienen IS NOT NULL
GROUP BY genre
HAVING COUNT(*) >= 3
ORDER BY genre;| genre | erschienene_spiele |
|---|---|
| Action | 3 |
| Strategie | 3 |
In der vorherigen Übung hatte auch Adventure 3 Spiele. Aber eines davon, Mystery Manor, ist noch nicht erschienen, und WHERE lässt es vor dem Zählen weg. Adventure hat dann nur 2 Spiele, und HAVING wirft es heraus. Action hatte 4 Spiele und zählt jetzt nur die 3, die erschienen sind.
Woher weißt du, wohin eine Bedingung gehört? Frage dich, ob du sie entscheiden kannst, indem du eine Zeile ansiehst. „Schon erschienen“, „bezahlt“, „aus Hamburg“: Eine Zeile genügt, also WHERE. „Mindestens 3 Spiele“, „mehr als 60 € insgesamt“, „im Durchschnitt 4 Sterne“: Du brauchst die ganze Gruppe, also HAVING. Eine Bedingung für die Spalte, nach der du gruppierst, wie genre = 'Action', würde in beiden funktionieren, aber setze sie in WHERE: Die Datenbank gruppiert dann keine Zeilen, die sie ohnehin wegwirft.
Typischer Fehler: eine Bedingung über Zeilen in HAVING. Andere Datenbanken melden einen Fehler, weil die Spalte nicht in GROUP BY steht. SQLite nicht: Es prüft das Erscheinungsdatum eines Spiels jeder Gruppe und behält oder verwirft danach die ganze Gruppe. Hier behält es alle Genres mit allen ihren Spielen:
SELECT genre, COUNT(*) AS erschienene_spiele
FROM spiele
GROUP BY genre
HAVING erschienen IS NOT NULL
ORDER BY genre;| genre | erschienene_spiele |
|---|---|
| Action | 4 |
| Adventure | 3 |
| … | … |
Kein Fehler, nur ein falsches Ergebnis: Action hat wieder 4 Spiele, darunter Robot Rebellion, das noch nicht erschienen ist.
So schreibst du es:
Anweisungen
- 1
Zähle von jedem Kunden nur die bezahlten Bestellungen (
status'bezahlt') und zeige die Kunden mit mindestens 3 davon:kunde_idund die Anzahl in einer Spaltebezahlte_bestellungen, sortiert nachkunde_id:kunde_id bezahlte_bestellungen 1 4 2 3 3 4 4 3 - 2
Zähle darunter die Kunden, die 2024 oder später beigetreten sind, in jeder Stadt, und zeige nur die Städte mit mindestens 2 von ihnen:
stadtund die Anzahl in einer Spalteneue_kunden, sortiert nach der Stadt:stadt neue_kunden Berlin 3 Hamburg 2 Leipzig 2