Ga naar hoofdinhoud

Het verschil tussen WHERE en HAVING in SQL

Ontdek hoe WHERE rijniveau-data filtert in SQL-query’s, terwijl HAVING gegroepeerde data na aggregatie filtert, en beheers hun verschillende toepassingen in SQL-querying.
Bijgewerkt 1 jun 2026  · 8 min lezen

WHERE en HAVING zijn twee essentiële clausules in SQL. Of je nu supergeavanceerde query’s of heel eenvoudige schrijft, je zult beide nodig hebben. Je kunt WHERE en HAVING zien als broer en zus: ze hebben een vergelijkbare functie (filteren) en komen vaak samen voor. Maar net als bij siblings hebben ze ook hun eigen kenmerken en rollen. 

Als je trying-to-make-sense-of WHERE en HAVING bent, meld je dan aan voor onze skill track SQL Fundamentals als een sterk en compleet startpunt. Je leert er over de verschillende SQL-clausules, de volgorde van uitvoering in SQL, het optimaliseren van SQL-query’s en nog veel meer essentiële onderwerpen.  

Het korte antwoord: WHERE vs. HAVING 

Het korte antwoord, en de bron van verwarring voor veel mensen, is dat WHERE werkt op rijniveau-data, terwijl HAVING werkt op gegroepeerde data. Hierbij een richtlijn:

  • WHERE filtert rijen vóórdat er grouping of aggregatie plaatsvindt. Het is van toepassing op individuele rijen en kan niet met aggregatiefuncties worden gebruikt.

  • HAVING filtert groepen nadat de grouping en aggregatie zijn uitgevoerd. Het is van toepassing op de resultaten van aggregatiefuncties en wordt gebruikt in combinatie met GROUP BY.

Een snel voorbeeld om het verschil te laten zien 

Laten we een snel voorbeeld bekijken. Wil je meedoen in je eigen workflow, download dan de dataset met huurwoningen uit deze GitHub-repository.

Stel nu dat we alle woningen in onze dataset willen teruggeven met een huurprijs van minder dan $500. Het detailniveau van elke rij in de dataset (één woning per rij) komt overeen met het detailniveau van de queryvoorwaarde. Daarom gebruiken we WHERE in de volgende query:

SELECT *
FROM rentals
WHERE rental_price < 500

Het resultaat ziet er zo uit. Let op dat er 118 rijen worden geretourneerd.

Eenvoudig filteren van rijen met SQL WHERE

Eenvoudig rijen filteren met WHERE. Afbeelding door de auteur.

Stel nu dat we geen tabel met woningen willen, maar met steden die een gemiddelde huurprijs hebben van minder dan $2.700. In plaats van elke rij te laten overeenkomen met een woning, groeperen we de rijen en aggregeren we de huurprijs tot een gemiddelde huurprijs per stad. Daarom gebruiken we HAVING, zoals in deze query:

SELECT city, AVG(rental_price) AS average_rent
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;

En het resultaat zou dit zijn. Let op: er is maar één resultaat. 

Eenvoudig groeperen filteren met SQL HAVING

Eenvoudig groepen filteren met HAVING. Afbeelding door de auteur.

WHERE, HAVING en de volgorde van uitvoering in SQL

We zien dat WHERE werkt met filteren op rijniveau, terwijl HAVING werkt met filteren op aggregatieniveau. Dit verschil begrijpen legt ook de basis om te leren over de volgorde waarin SQL-clausules worden uitgevoerd

WHERE wordt geëvalueerd vóór GROUP BY, en direct na FROM (en JOIN als die aanwezig is); het kan niet omgaan met grouping of aggregatie. WHERE treedt in werking voordat er enige aggregatie is gedaan. Daarom werkt het alleen op rijniveau-data. 

HAVING daarentegen komt pas na het uitvoeren van de GROUP BY-clausule. Dat betekent dat het pas wordt toegepast nadat de tabel is getransformeerd en gegroepeerd op een niveau dat verschilt van de granulariteit van de brontabel. HAVING werkt op de nieuwe, getransformeerde versie van de tabel. 

De WHERE-clausule gebruiken in SQL

Laten we een stap terug doen en elke clausule afzonderlijk bekijken. We beginnen met de WHERE-clausule.

WHERE-syntax en -statements

WHERE kan worden gebruikt in drie verschillende SQL-statements: SELECT, UPDATE en DELETE.

WHERE in SELECT-statements

In SELECT-statements, die worden gebruikt om data uit de database op te halen, speelt WHERE zijn directe rol in filteren op rijniveau en staat het, zoals bekend, direct na de FROM-clausule, zoals we zien in de volgende query:

SELECT column1, column2… etc.
FROM table_name
WHERE condition;

WHERE gebruikt met SELECT is de plek waar de WHERE-clausule het vaakst wordt verward met HAVING

WHERE in UPDATE-statements

Daarnaast speelt WHERE een belangrijke rol in UPDATE-statements om precies de rij aan te wijzen waar de data-update moet plaatsvinden, zoals we zien in de volgende syntax:

UPDATE table_name
SET column_name1 = value1, column_name2 = value2… etc.
WHERE condition;

WHERE in DELETE-statements

WHERE is ook een nuttige toevoeging aan DELETE-statements om de records (rijen) aan te wijzen die moeten worden verwijderd, zoals we hier zien:

DELETE FROM table_name
WHERE condition;

Hoe schrijf je WHERE-voorwaarden

WHERE-voorwaarden worden geschreven als een eenvoudige logische expressie. Die bestaat uit drie delen: de variabele/operand, de voorwaarde en de waarde/uitkomst. Laten we de opties voor WHERE-voorwaarden bekijken, met zowel vergelijkings- als logische operatoren.  

Operatorsymbool Omschrijving Datatype operand
= Gelijk aan (op datum) Numeriek, Tekst, Datum/timestamp, Boolean
< Kleiner dan (vóór datum) Numeriek, Datum/timestamp
> Groter dan (na datum) Numeriek, Datum/timestamp
<= Kleiner dan of gelijk aan (op of vóór datum) Numeriek, Datum/timestamp
>= Groter dan of gelijk aan (op of na datum) Numeriek, Datum/timestamp
<> (!=) Niet gelijk aan (niet op datum) Numeriek, Tekst, Datum/timestamp, Boolean
IN Gelijk aan meer dan één waarde (op meerdere data) Numeriek, Tekst, Datum/timestamp, Boolean (wel onzinnig!)
LIKE Komt overeen met tekstpatroon (met wildcards) Tekst
BETWEEN Ligt binnen een bereik Numeriek, Datum/timestamp
AND Combineert meerdere voorwaarden, allemaal moeten waar zijn Logisch (Boolean)
OR Combineert meerdere voorwaarden, minstens één moet waar zijn Logisch (Boolean)
NOT Keert een voorwaarde om Logisch (Boolean)
IS NULL Controleert op null-waarden Alle datatypen
IS NOT NULL Controleert op niet-null-waarden Alle datatypen

Hier is een voorbeeld waarin we NOT gebruiken samen met de vergelijkingsoperator IN:

SELECT *
FROM rentals
WHERE city NOT IN ('Cairo', 'Giza');

De statement retourneert alle woningen die noch in de stad Cairo noch in Giza liggen.

NOT gebruiken met WHERE

Woningen buiten Cairo en Giza. Afbeelding door de auteur.

Gebruikssituaties voor WHERE

Omdat WHERE werkt met SELECT-, UPDATE- en DELETE-statements, kun je drie use-cases voorzien: filteren op rijniveau, data-opvraging en datamanipulatie.

Filteren op rijniveau

We kunnen rijen in onze tabel filteren op basis van één of meer voorwaarden. De volgende query filtert rijen zodat alleen villa’s worden opgenomen.

SELECT *
FROM rentals
WHERE type = ‘villa’;

NOT gebruiken met WHERE

Villa’s selecteren. Afbeelding door de auteur.

Data-opvraging

WHERE kan worden gebruikt om een specifiek datapunt op te halen waar we naar op zoek zijn. Dit lijkt op filteren op rijniveau maar is specifieker. Stel dat we de ID willen weten van de woning die op 1 januari 2022 in Cairo beschikbaar was, dan kunnen we de volgende query gebruiken:

SELECT property_id
FROM rentals
WHERE available_date = '2022-01-01'
AND city = 'Cairo';

Filteren op rijniveau met WHERE

Een datapunt ophalen. Afbeelding door de auteur.

Datamanipulatie

Tot slot is WHERE erg handig om waarden te wijzigen en specifieke records in je database te verwijderen. Stel bijvoorbeeld dat we ontdekten dat woning 171 eigenlijk niet huisdiervriendelijk is; dan kunnen we de kolom pet_friendly aanpassen met WHERE in een UPDATE-statement als volgt:

UPDATE rentals
SET pet_friendly = false
WHERE property_id = 171;

De HAVING-clausule gebruiken in SQL

Nu is het tijd om met dezelfde diepgang naar de HAVING-clausule te kijken. 

HAVING-syntax en -statements

Allereerst moeten we weten dat de HAVING-clausule alleen kan worden gebruikt in SELECT-statements. De enige mogelijke syntax is daarom als volgt:

SELECT grouped_column, aggregate_function(aggregated_column)… etc.
FROM table_name
GROUP BY grouped_column
HAVING condition

Let op: je kunt meer dan één gegroepeerde kolom en meer dan één geaggregeerde kolom toevoegen. Hieronder zien we voorbeelden.

Hoe schrijf je HAVING-voorwaarden

Net als WHERE worden HAVING-voorwaarden geschreven als logische expressies, maar met één extra component: de aggregatiefunctie. Een HAVING-voorwaarde bestaat dus uit 1) Aggregatiefunctie, 2) variabele/operand, 3) vergelijkingsoperator en 4) waarde/uitkomst.

Aggregatiefuncties met HAVING

SQL heeft in hoofdzaak vijf aggregatiefuncties, plus een zesde in een bijzonder geval. Deze functies zijn:

Aggregatiefunctie Geschikt datatype
SUM() Numeriek
AVG() Numeriek
MIN() Numeriek, Tekst, Datum/timestamp
MAX() Numeriek, Tekst, Datum/timestamp
COUNT() Numeriek, Tekst, Datum/timestamp, Boolean

Laten we een voorbeeld proberen. Hier gebruiken we de functie COUNT() met GROUP BY om een frequentietabel te maken, en gebruiken we de HAVING-voorwaarde als filter. Concreet willen we de steden weten die 150 keer of minder voorkomen, wat in deze context te maken heeft met het aantal registraties. We kunnen deze query gebruiken:

SELECT city, COUNT(*) AS properties_count
FROM rentals
GROUP BY city
HAVING COUNT(*) <= 150;

MAX() gebruiken met HAVING

COUNT() gebruiken met HAVING. Afbeelding door de auteur.

Vergelijkings- en logische operatoren

HAVING accepteert alle vergelijkings- en logische operatoren die WHERE accepteert. Het enige verschil is dat het geschikte datatype bij HAVING in de eerste plaats afhangt van de aggregatiefunctie, zoals we in de tabel hierboven zien.

Gebruikssituaties voor HAVING

In tegenstelling tot WHERE kan HAVING niet worden gebruikt in UPDATE- en DELETE-statements; HAVING wordt alleen gebruikt voor data-opvraging. Grofweg vertaalt dit zich naar twee scenario’s:

Filteren op groepsniveau

Dit is het gebruikelijke en normale gebruik van HAVING. Een voorbeeld is alleen die steden teruggeven met gemiddelde huurprijzen onder $2.700.

SELECT city, AVG(rental_price) AS avg_price
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;

Filteren tot één rij

Dit is een ongebruikelijk geval, maar HAVING kan worden gebruikt om een aggregatie met één rij, zoals een metric of KPI, terug te geven, maar alleen als die aan een bepaalde voorwaarde voldoet. Dit kan worden bereikt door HAVING te gebruiken zonder GROUP BY. In het volgende voorbeeld retourneren we de gemiddelde huurprijs alleen als die lager is dan $2.800. Als de maatregel aan de voorwaarde voldoet, krijgen we een resultaat met één rij. Zo niet, dan krijgen we een lege tabel.

SELECT AVG(rental_price) as avg_price
FROM rentals
HAVING AVG(rental_price) > 2800;

WHERE en HAVING combineren

WHERE en HAVING kunnen worden gecombineerd om tabellen te filteren vóór en na aggregatie. In het volgende voorbeeld geven we het aantal woningen per stad terug, waarbij we alleen woningen meetellen die huisdiervriendelijk zijn, en filteren we naar alleen steden met meer dan 80 woningen.

SELECT city, COUNT(*) AS number_properties
FROM rentals
WHERE pet_friendly = true
GROUP BY city
HAVING COUNT(*) > 80;

WHERE combineren met HAVING

Basale combinatie van WHERE en HAVING. Afbeelding door de auteur.

Het verschil tussen WHERE en HAVING qua performance

We weten dat de WHERE-clausule wordt toegepast vóór grouping of aggregatie. Om die reden is WHERE efficiënter voor het filteren van individuele rijen, omdat het vroeg in de query het aantal te verwerken rijen vermindert. 

We weten aan de andere kant dat de HAVING-clausule wordt toegepast ná aggregatie en het resultaat filtert op basis van gegroepeerde data. Omdat dit gebeurt nadat alle rijen zijn gegroepeerd, is het over het algemeen minder efficiënt dan WHERE, al is het wel noodzakelijk voor voorwaarden die aggregatiefuncties omvatten.

Laten we naar deze query kijken:

SELECT city, COUNT(*)
FROM rentals
GROUP BY city
HAVING rental_price < 2700;

Deze query is inefficiënt omdat de voorwaarde rental_price niet afhankelijk is van een aggregatie — het filtert individuele rijen. Deze query zal eerst alle verhuurobjecten per stad groeperen, ze tellen en dán het resultaat filteren, wat inefficiënt is omdat er onnodige rijen worden verwerkt. Daarom zou dit een snellere query zijn geweest:

SELECT city, COUNT(*)
FROM rentals
WHERE rental_price < 2700
GROUP BY city;

Optimalisatietips voor WHERE en HAVING

Op basis van het voorgaande zien we enkele goede praktijken om ons gebruik van de clausules WHERE en HAVING te optimaliseren. Dit is belangrijk bij grote datasets.

  1. Wees heel selectief: Filter precies op de waarden waarop je moet filteren en niet meer. Dit helpt het aantal rijen in de view te verminderen en verhoogt zo de efficiëntie van de query.

  2. Houd het simpel: Haal onnodige voorwaarden, aggregaties en typecasts weg. Al deze extra’s hebben zeker een rekentechnische prijs.

  3. Filter vroeg: Als je een aggregatie op groepsniveau doet, prefilter de rijen met WHERE om het groeperingsproces te versnellen. Zo verlaag je het aantal rijen dat in de grouping verwerkt moet worden.

Vergelijkingstabel

Laten we onze gedachten samenvatten in een handige tabel:

Vergelijking WHERE HAVING
Hoofddoel Filteren op rijniveau Filteren op groepsniveau
Basissyntax SELECT column1, column2... FROM table_name WHERE condition; SELECT grouped_column, aggregate_function(aggregated_column)... FROM table_name GROUP BY grouped_column HAVING condition;
Volgorde van evaluatie Voor GROUP BY Na GROUP BY
Compatibele statements SELECT, UPDATE, DELETE  SELECT
Voorwaarden Kunnen geen aggregatiefuncties bevatten Moeten aggregatiefuncties bevatten
Use-cases Filteren op rijniveau Data-opvraging Datamanipulatie Filteren op groepsniveau Filteren tot één rij
Subquery’s Kan werken met subquery’s Moeten als CTE’s worden geschreven

Conclusie

In dit artikel hebben we het belangrijkste verschil tussen WHERE en HAVING in SQL verkend: de WHERE-clausule filtert rijen vóór aggregatie, terwijl de HAVING-clausule gegroepeerde data filtert ná aggregatie. We hebben ook enkele minder bekende verschillen besproken, zoals het feit dat WHERE kan werken met SELECT-, UPDATE- en DELETE-statements, terwijl HAVING alleen werkt met SELECT. Ook hebben we kort over performance gesproken.

De SQL Basics Cheat Sheet van DataCamp geeft een fijne samenvatting van de clausules WHERE en HAVING, en wat houvast bij het filteren in SQL. Als je net begint met SQL, kijk dan zeker ook naar de skill track SQL Fundamentals en de career track Associate Data Analyst in SQL


Islam Salahuddin's photo
Author
Islam Salahuddin

Islam is data consultant bij The KPI Institute. Met een achtergrond in de journalistiek heeft Islam brede interesses, waaronder schrijven, filosofie, media, technologie en cultuur.

Veelgestelde vragen

Wat is het verschil tussen WHERE en HAVING?

WHERE filtert op rijniveau, terwijl HAVING op groepsniveau filtert.

Kan ik WHERE en HAVING in één query combineren?

Ja, en het is sterk aan te raden om WHERE te gebruiken als je HAVING gaat gebruiken.

Kan WHERE werken met aggregatiefuncties zoals HAVING?

Nee, alleen HAVING kan werken met aggregatiefuncties.

Werken WHERE en HAVING met dezelfde vergelijkings- en logische operatoren?

Ja, ze werken allebei met dezelfde operatoren, omdat WHERE- en HAVING-voorwaarden worden geschreven als logische expressies.

Kan ik HAVING gebruiken zonder GROUP BY?

HAVING wordt meestal gebruikt na groeperen met GROUP BY. De enige uitzondering hierop is filteren van een weergave met één waarde (zoals het berekenen van één metric).

Onderwerpen

Leer SQL met DataCamp

Cursus

Gegevens manipuleren in SQL

4 Hr
323.6K
Bekijk detailsRight Arrow
Begin met de cursus
Meer zienRight Arrow
Gerelateerd

blog

AI vanaf nul leren in 2026: een complete gids van de experts

Ontdek alles wat je moet weten om in 2026 AI te leren, van tips om te beginnen tot handige resources en inzichten van industrie-experts.
Adel Nehme's photo

Adel Nehme

15 min

Meer zienMeer zien