CodeGym /Kurse /SQL SELF /Aggregierte Daten filtern mit HAVING

Aggregierte Daten filtern mit HAVING

SQL SELF
Level 8 , Lektion 1
Verfügbar

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:

  1. Zuerst werden die Zeilen mit WHERE gefiltert.
  2. Dann werden die Daten mit GROUP BY gruppiert.
  3. Auf die Gruppenergebnisse werden Aggregatfunktionen angewendet.
  4. Am Ende wird das Ergebnis mit HAVING gefiltert.

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 faculty mit GROUP BY.
  • Dann zählt die Aggregatfunktion COUNT(*), wie viele Studierende es pro Fakultät gibt.
  • Am Ende schmeißt HAVING alle 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:

  1. 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.

  2. GROUP BY: Zeilen gruppieren.

    Nach dem Filtern werden die Zeilen anhand der in GROUP BY angegebenen Spalten zu Gruppen zusammengefasst.

  3. Aggregatfunktionen:

    Auf die gruppierten Daten werden Aggregatfunktionen wie COUNT(), AVG(), SUM() usw. angewendet.

  4. 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.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION