Gruppen mit GROUP BY
Wie viele Spiele jedes Genres hat der Shop? Mit dem, was du bisher kennst, bräuchtest du für jedes Genre eine Abfrage: WHERE genre = 'Action', WHERE genre = 'Adventure' und so weiter, achtmal. GROUP BY erledigt das in einer Abfrage:
SELECT genre, COUNT(*) AS anzahl_spiele
FROM spiele
GROUP BY genre
ORDER BY genre;| genre | anzahl_spiele |
|---|---|
| Action | 4 |
| Adventure | 3 |
| Puzzle | 2 |
| RPG | 2 |
| Rennspiel | 2 |
| Simulation | 2 |
| Sport | 2 |
| Strategie | 3 |
GROUP BY genre teilt die Zeilen in Gruppen auf: Alle Zeilen mit demselben Genre kommen in eine Gruppe. Die vier Action-Spiele (Shadow Ninja, Star Pilots, Zombie Town und Robot Rebellion) bilden eine Gruppe, die drei Adventure-Spiele eine andere und so weiter. Die Aggregatfunktion arbeitet dann auf jeder Gruppe einzeln, und das Ergebnis hat eine Zeile für jede Gruppe: das Genre und die Anzahl seiner Spiele.
Jede Aggregatfunktion funktioniert so, und du kannst mehrere gleichzeitig benutzen:
SELECT genre, MIN(preis) AS guenstigstes, MAX(preis) AS teuerstes
FROM spiele
GROUP BY genre
ORDER BY genre;| genre | guenstigstes | teuerstes |
|---|---|---|
| Action | 25 | 40 |
| Adventure | 15 | 25 |
| Puzzle | 5 | 10 |
| … | … | … |
GROUP BY steht nach FROM und WHERE und vor ORDER BY. Die Gruppen kommen vielleicht sortiert, aber nichts garantiert es, also füge ORDER BY hinzu, wenn die Reihenfolge wichtig ist. Zeilen, die in der Spalte NULL haben, bilden eine eigene Gruppe.
Was kann in SELECT neben einer Aggregatfunktion stehen? Die Spalten, nach denen du gruppierst, denn sie sind in der ganzen Gruppe gleich, und Aggregatfunktionen, die aus der Gruppe einen Wert berechnen. Sonst nichts: Eine Gruppe hat viele Zeilen mit verschiedenen Titeln, welchen sollte das Ergebnis also zeigen?
Typischer Fehler: eine Spalte, die nicht in GROUP BY steht. Die meisten Datenbanken melden einen Fehler, dass die Spalte in GROUP BY vorkommen oder in einer Aggregatfunktion benutzt werden muss. SQLite nicht; es nimmt den Titel aus einer Zeile jeder Gruppe:
SELECT genre, titel, COUNT(*) AS anzahl_spiele
FROM spiele
GROUP BY genre;| genre | titel | anzahl_spiele |
|---|---|---|
| Action | Shadow Ninja | 4 |
| Adventure | Lost Temple | 3 |
| … | … | … |
Jede Zeile zeigt jetzt den Titel eines Spiels neben der Anzahl der Spiele des ganzen Genres, und das ergibt keinen Sinn. Wenn du ein solches Ergebnis siehst, prüfe, ob jede Spalte in SELECT entweder in GROUP BY steht oder in einer Aggregatfunktion.
So schreibst du es:
Anweisungen
- 1
Zähle die Kunden in jeder Stadt: Zeige die Stadt und die Anzahl ihrer Kunden in einer Spalte
anzahl_kunden, sortiert nach der Stadt. Die Kunden ohne Stadt bilden auch eine Gruppe:stadt anzahl_kunden NULL 2 Berlin 3 Dresden 2 Hamburg 4 Leipzig 3 - 2
Berechne darunter die Summe jeder Bestellung aus
positionen: die ID der Bestellung (bestellung_id) und die Summe vonmenge * preisin einer Spaltebestellsumme, sortiert nachbestellung_id:bestellung_id bestellsumme 1 25 2 35 3 40 4 40 5 65 6 30 … …