Om effectief aggregaties met filtering op "niveaus" te bouwen (bijvoorbeeld, eerst filteren, dan sommen berekenen per groep, en vervolgens voor de hele dataset), worden vensterfuncties (OVER()) en geneste GROUP BY gebruikt.
Voorbeeld: Laten we de maximale bestelsom per manager vinden, maar alleen onder bestellingen met de status 'betaald', en vervolgens de naam van de manager met de absolute maximum onder alle weergeven.
WITH BetaaldeOrders AS ( SELECT ManagerID, SUM(OrderAmount) AS TotaalBetaald FROM Orders WHERE Status = 'betaald' GROUP BY ManagerID ), MetMax AS ( SELECT *, MAX(TotaalBetaald) OVER() AS MaxTotaalBetaald FROM BetaaldeOrders ) SELECT ManagerID, TotaalBetaald FROM MetMax WHERE TotaalBetaald = MaxTotaalBetaald;
Deze benadering (CTE + vensterfuncties) maakt het mogelijk om gelaagde filtering en aggregatie te implementeren.
Val: "Wat is het verschil tussen het uitvoeren van de WHERE-filter vóór de groepering (GROUP BY) en het toepassen van HAVING erna? Hoe komt dit vaak naar voren in rapportages?"
Antwoord: WHERE verwijdert rijen nog voor de groepering, wat zorgt voor een strikte invoerset. HAVING filtert de geaggregeerde groepen — daarom kan het tijdelijk "overbodige" rijen achterlaten als de filter logisch niet consistent is. Een onjuiste plaatsing van de filter leidt vaak tot fouten in de uiteindelijke aggregaten of tot onjuiste rapportresultaten.
-- We verkrijgen de som alleen over 'betaald', via WHERE SELECT ManagerID, SUM(OrderAmount) FROM Orders WHERE Status = 'betaald' GROUP BY ManagerID; -- Of we berekenen sommen voor allemaal, en knippen dan met HAVING SELECT ManagerID, SUM(OrderAmount) FROM Orders GROUP BY ManagerID HAVING SUM(OrderAmount) > 1000;
Verhaal
Project: Rapporten over verkoop, verificatie-audit.
Fout: De ontwikkelaar paste HAVING Status='betaald' toe in plaats van WHERE, waardoor de aggregaten per ongeluk ook niet-betaalde bestellingen omvatten, wat leidde tot een verkeerde berekening van de jaarlijkse KPI's van het personeel.
Verhaal
Project: Bankanalyses.
Fout: Bij een complexe aggregatie probeerden ze een vensterfunctie toe te passen zonder PARTITION BY, waardoor de aggregaten over de hele tabel in plaats van over de groep werden berekend. Het budget van de afdeling werd onjuist berekend — het moest handmatig worden hersteld.
Verhaal
Project: Webshop, statistieken van bestellingen.
Fout: Het inbedden van vensterfuncties in een subquery werd niet meegerekend tijdens de optimalisatie — hierdoor deed de server meerdere keren gegevensverwerking, waardoor de query 20 keer langzamer werd dan simpelweg met dubbele GROUP BY.