ProgrammatieSQL analist

Hoe implementeer je effectieve aggregatie met gelaagde filtering met behulp van vensterfuncties en groeperingen in SQL? Wat zijn de verschillen tussen de benaderingen en welke fouten maken ontwikkelaars vaak?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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.

  • Groepering via GROUP BY aggregeert alleen op de geselecteerde velden; het uitsluiten van de invloed van "externe" rijen kan alleen door een voorafgaande filter (WHERE) te gebruiken.
  • Vensterfuncties maken het mogelijk om aggregaten te berekenen over bepaalde fragmenten van gegevens, terwijl ze filters toepassen op de resulterende set (bijvoorbeeld, alleen onder rijen van dezelfde groep).

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.

Vraag met een val.

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;

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp.


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.