Zurück zur Artikelliste Artikel
4 Leseminuten

HAVING vs. WHERE in SQL: Was Sie wissen sollten

In diesem Artikel geht es um die WHERE- und HAVING-Klauseln von SQL. Beide Klauseln sind Teil der Grundlagen des SQL-Befehls SELECT. Sie haben ähnliche Verwendungszwecke, aber es gibt auch wichtige Unterschiede, die jede Person, die SQL verwendet, kennen sollte. Schauen wir uns an, was hinter der HAVING vs. WHERE Debatte steckt.

In diesem Artikel gehen wir davon aus, dass wir für eine staatliche Sozialbehörde arbeiten, die Menschen oder Familien unterstützt, deren Einkommen unter einem bestimmten Schwellenwert liegt. Diese Behörde verwendet mehrere Kennzahlen, um Personen oder Familien zu identifizieren, die Hilfe benötigen.

Schauen wir uns zunächst den Beispieldatensatz an. Im weiteren Verlauf des Artikels werden wir dann Abfragen auf der Grundlage dieses Datensatzes erstellen.

Beispieldatensatz

Dieser Datensatz beschreibt Personen, die zu vier Familien gehören, die in zwei Städten leben. Der Einfachheit halber nehmen wir an, dass last_name die Familie identifiziert. Die Idee ist, Metriken auf der Ebene der Personen und der Familien zu erhalten.

TABLE Persons

namelast_namebirth_dateyear_incomecity
MaryRoberts1964-01-1178000Oklahoma
PeterRoberts1962-09-2586500Oklahoma
JohnRoberts1999-06-030Oklahoma
SueRoberts1996-03-060Oklahoma
MelindaRoberts1998-04-040Oklahoma
GeorgeHudson1953-02-2348000Oklahoma
NancyHudson1958-12-0665000Oklahoma
AnnHudson1979-04-0235000Oklahoma
CarlGibson1963-04-03102800Phoenix
LiGibson1963-12-2796000Phoenix
KateBishop1994-07-10920000Phoenix
MarkBishop2018--9-130Phoenix

Nun gut. Jetzt, wo wir den Datensatz gesehen haben, können wir loslegen!

WHERE und HAVING: Einfache Beispiele

Die WHERE- und HAVING-Klauseln fungieren, vereinfacht ausgedrückt, als Filter; sie entfernen Datensätze oder Daten, die bestimmte Kriterien nicht erfüllen, aus dem Endergebnis einer Abfrage. Sie werden jedoch auf unterschiedliche Datensätze angewendet. Das ist der wichtige Punkt, den man über WHERE und HAVING wissen muss: WHERE filtert auf der Ebene der Datensätze, während HAVING auf der Ebene der "Gruppe von Datensätzen" filtert.

Lassen Sie uns einige Beispiele sehen.

Hier ist eine Beispielabfrage, die die WHERE-Klausel verwendet: Angenommen, wir möchten die Namen von Personen mit einem Jahreseinkommen von mehr als 100.000 $ ermitteln. Wir müssen auf Datensatzebene filtern (oder verwerfen), also verwenden wir für diese Abfrage die WHERE-Klausel anstelle der HAVING-Klausel:

Abfragetext zum Kopieren und Einfügen:

SELECT name, last_name
FROM  persons
WHERE year_income > 100000;

WHERE vs. HAVING

Versuchen wir nun eine ähnliche Abfrage, aber dieses Mal mit der HAVING-Klausel: Nehmen wir an, wir wollen die last_name von Familien mit einem Haushaltseinkommen (d.h. das summierte Einkommen aller Familienmitglieder) über 100.000 $ erhalten. Dies ist ein klarer Fall für die Verwendung der HAVING-Klausel, da wir nicht nach Datensätzen filtern müssen. (Wir werden den Datensatz einer Person nicht verwerfen, weil sie weniger als 100.000 $ verdient.) Die Idee ist, nach dem Familieneinkommen zu filtern, also müssen wir die Personen nach last_name gruppieren und HAVING verwenden, um die Personengruppen zu filtern, wie unten gezeigt:

Abfragetext zum Kopieren und Einfügen:

SELECT 	last_name,
		SUM(year_income) AS "family_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income) > 100000;

WHERE vs. HAVING

KOMPLEXE HAVING-KLAUSELN

Wir können beliebig viele Aggregatfunktionen in der Bedingung der HAVING-Klausel verwenden. Fahren wir mit unserer Analyse der Familieneinkommen fort und berechnen wir das durchschnittliche Einkommen pro Mitglied für jede Familie. Wir wollen Familien ermitteln, die weniger als 50.000 pro Person verdienen. Aus wirtschaftlicher Sicht kann diese Analyse mehr über die Familieneinkommen aussagen als die vorherige. Hier ist die Abfrage:

Abfragetext zum Kopieren und Einfügen:

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income)  / COUNT(*) < 50000;

WHERE vs. HAVING

Hinweis: Die HAVING-Klausel hat einige Einschränkungen; eine davon ist, dass Spalten auf Datensatzebene in der HAVING-Bedingung auch in der GROUP BY-Klausel erscheinen müssen.

Verwendung von WHERE und HAVING in der gleichen SQL-Abfrage

Es ist sehr üblich, WHERE und HAVING in der gleichen Abfrage zu verwenden. Führen wir eine Abfrage durch, um das gesamte Familieneinkommen und das Einkommen pro Mitglied für Familien in Oklahoma mit mehr als vier Mitgliedern zu erhalten:

Abfragetext zum Kopieren und Einfügen:

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
WHERE city = ‘Oklahoma’
GROUP BY last_name
HAVING COUNT(*) > 4;

WHERE vs. HAVING

WHERE und HAVING in komplexen Abfragen

Zum Abschluss des Artikels erstellen wir eine Abfrage, die Familien mit einem Haushaltseinkommen unterhalb des Durchschnittseinkommens in ihrer Stadt zurückgibt. Der knifflige Teil ist die Unterabfrage, die das Durchschnittseinkommen für eine bestimmte Stadt ermittelt. Bitte beachten Sie, dass wir eine andere Abfrage verwenden, da es sich um das Durchschnittseinkommen pro Stadt handelt; es basiert nicht auf der Anzahl der Mitglieder pro Familie, sondern auf der Anzahl der Familien in dieser Stadt, wie mit count(distinct last_name) berechnet.

Abfragetext zum Kopieren und Einfügen:

SELECT
  last_name, 
  COUNT(*) AS "members", 
  SUM(year_income) AS "family_income",
  SUM(year_income) / COUNT(*) AS "per_member_income"
FROM persons p
GROUP BY last_name
HAVING SUM(year_income) < (
  SELECT 
  SUM(year_income) / COUNT(distinct last_name) 
  FROM persons 
  WHERE city = p.city
);
WHERE vs. HAVING

Gelöst: WHERE vs. HAVING in SQL

Wir haben uns mehrere verschiedene Abfragen angesehen, die die WHERE- und HAVING-Klauseln von SQL verwenden. Wie wir bereits erwähnt haben, funktionieren beide Klauseln als Filter, aber jede gilt für eine andere Datenebene. Die WHERE-Klausel filtert auf der Ebene der Datensätze, während die HAVING-Klausel auf der Ebene der Gruppen filtert.

SQL ist eine äußerst flexible Sprache, und Sie können mit den WHERE- und HAVING-Klauseln Millionen von Kombinationen erstellen. An dieser Stelle möchte ich auf einen großartigen Kurs hinweisen, der mit den Themen dieses Artikels zusammenhängt: LearnSQL's Erstellen einfacher SQL-Berichte in SQL. Er richtet sich an Personen, die SQL-Grundlagen kennen und ihre Fähigkeiten zur Erstellung aussagekräftiger SQL-Berichte verbessern möchten. Gehen Sie weiter - erforschen Sie SQL!