Mit der GROUP BY-Klausel (engl.: gruppieren nach) hast Du die Möglichkeit, Datensätze in Gruppen einzuteilen. Wie das funktioniert? Ganz einfach: Jeder Datensatz wird genau einer Gruppe zugeordnet.
Sind alle Datensätze in Gruppen eingeteilt, kannst Du nur noch Informationen der Datengruppen abrufen oder Angaben zu einer gesamten Gruppe machen. Informationen der einzelnen Datensätze abzurufen ist dann nicht mehr möglich.
Der Unterschied zwischen ORDER BY und GROUP BY ist, dass ORDER BY eine finale Sortierung vornimmt, während GROUP BY, wie der Name schon sagt, Daten nach bestimmten Bedingungen gruppiert.
Um die GROUP BY-Klausel besser verstehen zu können, wollen wir uns die Menge der Filme pro Kategorie anschauen:
SELECT category_id, COUNT(film_id)
FROM film_category
GROUP BY category_film;
Ergebnis (Ausschnitt):
category_id |
COUNT(film_id) |
---|---|
1 |
64 |
2 |
66 |
3 |
60 |
4 |
57 |
5 |
58 |
... |
... |
Nehmen wir nun folgende Tabelle, gruppieren nach Kontinenten und lassen uns den Kontinent mit der größten Bevölkerung zuerst ausgeben. (Die Tabelle ist fiktiv und dient nur der Veranschaulichung.)
Kontinent |
Land |
Einwohnerzahl_in_Millionen |
---|---|---|
Europa |
Deutschland |
80 |
Europa |
Polen |
50 |
Europa |
Dänemark |
60 |
Nord-Amerika |
USA |
400 |
Nord-Amerika |
Kanada |
200 |
Afrika |
Etiopien |
20 |
Afrika |
Mali |
20 |
Nun die Abfrage:
SELECT Kontinent, SUM(Einwohnerzahl_in_Millionen) AS Einwohner FROM Laender
GROUP BY Kontinent
ORDER BY Einwohner DESC;
Ergebnis:
Kontinent |
Einwohner |
---|---|
Nord-Amerika |
600 |
Europa |
190 |
Afrika |
40 |
Nun solltest Du sowohl den Unterschied zwischen ORDER BY & GROUP BY verstanden haben, als auch gelernt haben, wie du beide gleichzeitig in einem SELECT-Statement verwendest.
Es ist auch möglich, eine SELECT-Anweisung mit einer GROUP BY-Klausel und einer WHERE-Bedingung zu kombinieren. Hierbei wählt die WHERE-Bedingung die Datensätze aus, die später gruppiert werden. Beachte bitte, dass Du in der WHERE-Bedingung keine Aggregatfunktionen benutzen kannst.
Wir wollen die Anzahl der Filme ausgeben, die als PG-13 eingestuft wurden.
SELECT category, COUNT(title)
FROM film_list
WHERE rating = "PG-13"
GROUP BY category;
Ergebnis (Ausschnitt):
category |
COUNT(title) |
---|---|
Action |
11 |
Animation |
19 |
Children |
14 |
Classics |
13 |
Comedy |
12 |
... |
... |
Mithilfe der HAVING-Klausel kannst Du spezifische Gruppen auswählen, sodass nur für Dich relevante Gruppen im Ergebnis angezeigt werden. Du wählst die Gruppen, die Du haben möchtest, anhand einer Eigenschaft aus, die nur die Gruppen beinhalten, die für Dich von Interesse sind.
Da Du dem WHERE-Operator keine Aggregatfunktionen übergeben kannst und der WHERE-Operator einzelne Tupel auswählt, brauchst Du die HAVING-Klausel, die die Eigenschaften der Gruppe überprüft, um Gruppen, die dich interessieren, auswählen zu können.
Wir wollen uns alle Kategorien anzeigen lassen, in denen es mehr als 60 Filme gibt.
SELECT category_id, COUNT(film_id)
FROM film_category
GROUP BY category_id
HAVING COUNT(film_id) > 60;
Ergebnis (Ausschnitt):
category_id |
COUNT(film_id) |
---|---|
1 |
64 |
2 |
66 |
6 |
68 |
7 |
62 |
8 |
69 |
... |
... |
Natürlich kannst Du auch WHERE, GROUP BY & HAVING in einer SELECT-Abfrage kombinieren. Es ist wichtig, dass Du die richtige Reihenfolge einhälst.
Als Erstes werden durch die WHERE-Klausel alle Datensätze selektiert, die für Dich von Interesse sind. Danach werden diese Datensätze mittels der GROUP BY-Klausel gruppiert und erst im Nachhinein werden die Gruppen, die von Interesse sind, mithilfe der HAVING-Klausel final ausgewählt.
Wieder wollen wir nur die Filme ihrer Kategorie nach gruppieren, die als PG-13 eingestuft wurden. Jedoch brauchen wir zusätzlich eine Auswahl von 15 Filmen.
SELECT category, COUNT(title)
FROM film_list
WHERE rating = "PG-13"
GROUP BY category
HAVING COUNT(title) > 15;
Ergebnis:
category |
COUNT(title) |
---|---|
Animation |
19 |
Drama |
22 |
Foreign |
19 |
Mögliche Fehlerquellen sind, dass Du nach der Gruppenbildung versuchst, einzelne Datensätze anzusprechen. Das ist nicht mehr möglich, da die Datensätze nun als "Pakete" vorliegen.
Willst Du auf einzelne Tupel zugreifen, um sie auszuwählen, so greife in der WHERE-Klausel zuerst auf die Tupel zu und gruppiere erst danach mit der GROUP BY-Klausel. Anschließend kannst du noch mit der HAVING-Klausel überprüfen, ob die "Pakete" bestimmte Bedingungen erfüllen.