Modulelessen (4/4)
Groepen filteren: HAVING
Als je eenmaal een resultaat per groep hebt (vorige les), wil je dat vaak ook
alleen de groepen behouden die aan een voorwaarde voldoen: afdelingen met meer
dan 2 personen, projecten met een gemiddeld budget boven de 100.000, gebruikers met
minimaal 10 bestellingen. Om dit te doen is WHERE niet genoeg.
Waarom WAAR niet genoeg is
WHERE filtert de tabelrijen, vóór aggregatie. Dus het kan niet zien
het resultaat van COUNT(*) of AVG(...): tegen de tijd dat WHERE wordt uitgevoerd, zijn deze
waarden zijn nog niet berekend.
-- ERROR: COUNT(*) doesn't exist yet when WHERE is evaluated
SELECT department_id, COUNT(*) AS count
FROM employees
WHERE COUNT(*) > 2 -- ❌ doesn't work
GROUP BY department_id;Om na aggregatie te filteren, is er een speciale clausule: HAVING.
De syntaxis
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column
HAVING condition_on_aggregate;-- Departments with more than 2 employees:
SELECT department_id, COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 2;HAVING is voor GROUP BY wat WHERE is voor FROM: hetzelfde idee
("filter"), maar na groepering toegepast op het aggregaat.
De logische volgorde van clausules
Om WHERE en HAVING nooit meer te verwarren, onthoud de volgorde waarin
SQL voert ze mentaal uit:
FROM/JOIN— bouwt de starttabel op door bronnen samen te voegen.WHERE— verwijdert de rijen die u niet interesseren.GROUP BY— verzamelt de resterende rijen in groepen.HAVING— verwijdert de groepen die je niet interesseren.SELECT— berekent de laatste kolommen (inclusief aggregaten).ORDER BY/LIMIT— opnieuw ordenen en knippen.
Belangrijke opmerkingen:
- in
WHEREkun je alleen tabelkolommen gebruiken; - in
HAVINGkunt u kolommen en aggregaties groeperen gebruiken.
-- Classic combo: filter first, group, filter the groups, sort.
SELECT d.name, AVG(e.salary) AS average
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
WHERE e.hired_on >= '2018-01-01' -- filter rows
GROUP BY d.name
HAVING AVG(e.salary) > 35000 -- filter groups
ORDER BY average DESC;Probeer het
Toon voor elke afdeling de naam (departments.name) en het aantal medewerkers, MAAR alleen voor afdelingen met minimaal 2 medewerkers. Twee kolommen, één rij per kwalificerende afdeling.
Toon hint
De voorwaarde 'minstens 2' wordt COUNT(*) >= 2 in HAVING.
Oplossing beschikbaar na 3 pogingen
Oefening beoordelen
Toon de afdelingen (departments.name) waarvan het gemiddelde salaris hoger is dan 35.000. Beschouw alleen werknemers die vanaf 2018 zijn aangenomen. Twee kolommen: naam en het gemiddelde. Sorteer op gemiddeld aflopend.
Toon hint
WHERE filtert de rijen (medewerkers ingehuurd vanaf 2018), HAVING filtert de groepen (gemiddeld > 35000).
Oplossing beschikbaar na 3 pogingen