GROUP BY und HAVING

Wir müssen die Leute nach gewissen Merkmalen einordnen, weil wir nicht wissen, wer die Terroristen sind.

Ich wette, Daskalov ist -

Lass mich in Ruhe mit deinem Daskalov und hör mir zu!

*hrml

Ich habe dir hier aufgeschrieben, wie das funktioniert. Fuchs dich rein, probier etwas rum, während ich alles vorbereite.

Stell dir vor, du hast eine Liste aller Personen. Und du willst die aufteilen nach Augenfarbe. Dann schreibst du:

SELECT p.nachname, p.augenfarbe
FROM personen p
GROUP BY p.augenfarbe;

Dann kriegst du als Ergebnis für jede Augenfarbe eine Zeile:

Jetzt fragst du dich, warum da bei »blau« oder »braun« nur ein Name steht. Es sind ja viele Leute mit blauen oder braunen Augen. Ganz einfach: In dieser Zelle stehen eigentlich viele Namen. Das kannst du mit GROUP_CONCAT sehen:

SELECT GROUP_CONCAT(p.nachname), p.augenfarbe
FROM personen p
GROUP BY p.augenfarbe;

Das ist natürlich ziemlich abartig, da ja eigentlich in einer Zelle nur ein Wert stehen soll. Vielleicht ist es einfacher, wenn du es mit COUNT(*) probierst, das kennst du ja schon:

SELECT COUNT(*), p.augenfarbe
FROM personen p
GROUP BY p.augenfarbe;

Jetzt hast du also alle Personen nach Augenfarbe getrennt (gruppiert, sozusagen) und gezählt, wie viele Ergebnisse du für die einzelnen Gruppen hast. Und für diese Gruppen kannst du jetzt bspw. alle Aggregatfunktionen anwenden, die du kennst. Wenn du also wissen möchtest, wie viele die einzelnen Gruppen durchschnittlich verdienen, schreibst du

SELECT AVG(p.monatlichesEinkommen), p.augenfarbe
FROM personen p
GROUP BY p.augenfarbe;

Das probierst du jetzt erst mal aus.

Ächz … Also, was könnte ich da machen … Ich schreib mir mal ein paar Dinge auf …

  • Familienstand ist bestimmt gut. Also wie viele Leute welchen Familienstand haben.
  • Die Anzahl der Leute, die in den einzelnen Straßen wohnen. Am besten mache ich mir da ein Alias für den COUNT-Teil und sortiere nach diesem Alias absteigend.
  • Welche Berufe sind die häufigsten? Da gruppiere ich wohl einfach nach Beruf und sortiere absteigend nach der Anzahl.
  • Da könnte ich ja gleich schauen, was die einzelnen Berufsgruppen durchschnittlich verdienen. Richtig schick wäre, wenn ich das noch so sortiere, dass die Berufsgruppen, die am häufigsten vertreten sind, oben stehen.

Hey, Kowalsky! Ich hab's gecheckt! Starten wir jetzt die Rasterfahndung?

Nein. Dir fehlt noch eine wichtige Sache. Hast du den anderen Zettel nicht gesehen?

HAVING

Stell dir vor, du hast nach den verschiedenen Berufen gruppiert. Dann kriegst du ziemlich viele Ergebnisse, weil es in dieser kleinen Stadt halt nur zwei Erzieherinnen und einen Ergotherapeuten gibt und so. Diese Abfrage:

SELECT count( * ) AS anzahl, p.beruf
FROM personen p
GROUP BY p.beruf
ORDER BY anzahl DESC;

spuckt halt fast 200 Ergebnisse aus, das wird viel zu unübersichtlich. Du möchtest vielleicht nur die Berufe sehen, von denen es mindestens 5 gibt. Und jetzt Achtung: Was du NICHT machen kannst, ist

falsch!

SELECT count( * ) AS anzahl, p.beruf
FROM personen p
WHERE anzahl > 4
GROUP BY p.beruf
ORDER BY anzahl DESC;

DENN: Die anzahl lässt sich nur berechnen, wenn schon gruppiert wurde (ist ja klar). Es kann aber erst gruppiert werden, wenn das WHERE schon ausgeführt wurde. Ist ja auch klar.

Anders ausgedrückt: Du kannst ein Aggregat (wie im Beispiel anzahl, was ja letztlich ein COUNT ist) nicht in der WHERE-Klausel verwenden. Die Abfrage muss erst ganz ausgeführt sein, erst DANN kannst du sie einschränken. Und das machst du mit HAVING:

SELECT count( * ) AS anzahl, p.beruf
FROM personen p
GROUP BY p.beruf
HAVING anzahl > 4
ORDER BY anzahl DESC;

Oh Gott … Das probiere ich einfach mal an den Abfragen aus, die ich vorhin gemacht habe …

  • Wie viele Leute haben welchen Familienstand - aber nur die Familienstände, von denen es mehr als 100 gibt.
  • Die Anzahl der Leute, die in den einzelnen Straßen wohnen. Aber nur die Straßen, wo mehr als 8 Leute wohnen.
  • Die Anzahl der Berufe - aber nur die, von denen es mehr als 4 gibt.
  • Und jetzt den Durchschnittsverdienst der einzelnen Berufe, aber nur von den Berufen, von denen es mehr als 4 Leute gibt.

Hey, Kowalsky - das ist ja easy! Ich glaube, ich habe es!

Prima - dann können wir ja loslegen!