Was wir noch nicht besprochen haben, ist wie filtert man Gruppen nach der Anwendung von Aggregaten? Manchmal brauchen wir nicht alle Fakultäten – nur die, wo es mehr als hundert Studierende gibt. Oder wir wollen nur die Abteilungen sehen, wo das Durchschnittsgehalt über 50.000 liegt. Heute schauen wir uns an, wie man aggregierte Daten mit HAVING filtert.
Wozu brauchen wir HAVING, wir haben doch WHERE? Kann man nicht einfach WHERE nach GROUP BY setzen? :)
So einfach ist das nicht! Erstens ist die Reihenfolge der Operatoren in SQL festgelegt und WHERE wird vor GROUP BY ausgeführt.
Kann man das vielleicht einfach nach GROUP BY verschieben?
Auch nicht! Sehr oft muss man die Zeilen der Tabelle vor der Gruppierung filtern. Dann gruppiert man die gefilterten Daten. Und dann will man nach der Gruppierung noch irgendwelche unnötigen Daten loswerden.
Vielleicht kann man einfach den Operator WHERE nehmen, ihn kopieren, HAVING nennen und nach GROUP BY platzieren?
Genau, so machen wir das! :)
Unterschied zwischen HAVING und WHERE
WHERE filtert Zeilen vor der Gruppierung.
Stell dir vor, du sortierst Kuchen nach Geschmack: Erdbeer- und Schokokuchen behältst du, die anderen kommen weg. Das ist ein Job für WHERE.
HAVING filtert, nachdem die Daten gruppiert wurden und die Aggregatfunktionen ihre Magie gemacht haben.
Zum Beispiel hast du die Kuchen schon nach Tischen gruppiert, gezählt wie viele es pro Tisch gibt und willst jetzt nur die Tische behalten, wo es mehr als drei Kuchen gibt.
Also wird HAVING benutzt, um Daten auf Gruppenebene zu filtern.
Syntax von HAVING
Die Syntax ist fast wie bei WHERE, aber es funktioniert ein bisschen anders:
SELECT spalten, aggregatfunktionen
FROM tabelle
GROUP BY spalten
HAVING bedingung;
Die Schritte sind:
- Zuerst werden die Zeilen mit
WHEREgefiltert. - Dann werden die Daten mit
GROUP BYgruppiert. - Auf die Gruppenergebnisse werden Aggregatfunktionen angewendet.
- Am Ende wird das Ergebnis mit
HAVINGgefiltert.
Beispiele für HAVING
Beispiel 1: Fakultäten mit vielen Studierenden filtern
Du willst wissen, welche Fakultäten an der Uni mehr als 100 Studierende haben. Angenommen, wir haben die Tabelle students:
| id | name | faculty |
|---|---|---|
| 1 | Alice | Engineering |
| 2 | Bob | Engineering |
| 3 | Charlie | Arts |
| 4 | Daisy | Business |
| 5 | ... | ... |
Query:
SELECT faculty, COUNT(*) AS student_count
FROM students
GROUP BY faculty
HAVING COUNT(*) > 100;
Was passiert hier:
- Erst gruppieren wir die Studierenden nach
facultymitGROUP BY. - Dann zählt die Aggregatfunktion
COUNT(*), wie viele Studierende es pro Fakultät gibt. - Am Ende schmeißt
HAVINGalle Fakultäten raus, wo es 100 oder weniger Studierende gibt.
Ergebnis:
| faculty | student_count |
|---|---|
| Engineering | 150 |
| Arts | 120 |
Beispiel 2: Abteilungen mit hohem Durchschnittsgehalt
Du willst nur die Abteilungen finden, wo das Durchschnittsgehalt der Mitarbeitenden über 50.000 liegt. Angenommen, wir haben die Tabelle employees:
| id | name | department | salary |
|---|---|---|---|
| 1 | Alice | IT | 60000 |
| 2 | Bob | HR | 45000 |
| 3 | Charlie | IT | 70000 |
| 4 | Daisy | HR | 52000 |
| 5 | ... | ... | ... |
Query:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
Ergebnis:
| department | avg_salary |
|---|---|
| IT | 65000 |
Wichtig: HAVING arbeitet mit den Ergebnissen, die nach GROUP BY berechnet wurden.
Reihenfolge von WHERE, GROUP BY und HAVING
Das Filtern mit WHERE und HAVING passiert in verschiedenen Schritten. Damit du den Unterschied besser verstehst, hier der Ablauf eines Queries Schritt für Schritt:
WHERE: Zeilen filtern.In diesem Schritt werden alle Zeilen der Tabelle bearbeitet. Wenn eine Zeile die
WHERE-Bedingung nicht erfüllt, kommt sie gar nicht weiter.GROUP BY: Zeilen gruppieren.Nach dem Filtern werden die Zeilen anhand der in
GROUP BYangegebenen Spalten zu Gruppen zusammengefasst.Aggregatfunktionen:
Auf die gruppierten Daten werden Aggregatfunktionen wie
COUNT(),AVG(),SUM()usw. angewendet.HAVING: Gruppen filtern.Jetzt werden nur die Ergebnisse der Aggregate bearbeitet. Die
HAVING-Bedingungen gelten nur für Gruppen.
Besonderheiten von HAVING
Besonderheit 1: Arbeiten mit Aggregaten
Der Hauptunterschied zwischen HAVING und WHERE ist das Arbeiten mit Aggregatfunktionen. Zum Beispiel:
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
In diesem Query kann man AVG(salary) nicht im WHERE verwenden, weil WHERE die Zeilen vor der Gruppierung bearbeitet. Ein Query wie:
SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;
führt zu einem Fehler: aggregate functions are not allowed in WHERE.
Besonderheit 2: Filtern ohne Gruppierung
Du kannst HAVING sogar ohne explizites GROUP BY verwenden. Dann wird das Query so interpretiert, als gäbe es nur eine Gruppe – alle Zeilen zusammen:
SELECT AVG(salary) AS avg_salary
FROM employees
HAVING AVG(salary) > 50000;
Praxibeispiel
Angenommen, wir haben einen Shop und eine Verkaufstabelle sales:
| id | product_id | sales_amount |
|---|---|---|
| 1 | 101 | 200.00 |
| 2 | 102 | 300.00 |
| 3 | 101 | 400.00 |
| 4 | 103 | 150.00 |
Query: Finde Produkte mit einem Gesamtumsatz über 500.
SELECT product_id, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING SUM(sales_amount) > 500;
Ergebnis:
| product_id | total_sales |
|---|---|
| 101 | 600.00 |
Typische Fehler
Aggregatfunktionen in WHERE verwenden:
Zum Beispiel:
SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;
Fehler: Aggregatfunktionen dürfen nicht in WHERE verwendet werden.
Fehler mit NULL:
Wenn die Daten NULL enthalten, kann das Filtern zu unerwarteten Ergebnissen führen. Zum Beispiel:
SELECT department, SUM(salary)
FROM employees
GROUP BY department
HAVING SUM(salary) > 0;
Wenn die Spalte salary nur NULL enthält, kann das Ergebnis null oder leer sein.
Glückwunsch! Jetzt kannst du schon sicher aggregierte Daten filtern! Denk dran: HAVING ist dein Schlüssel zur Analyse auf Gruppenebene, wo ein normales WHERE nicht mehr reicht.
GO TO FULL VERSION