Aggregatie met voorwaarden is een klassieke taak voor rapportage. In eerste instantie werden aparte queries met filters gemaakt om verschillende indicatoren te tellen. Al snel verscheen een compactere oplossing - voorwaardelijke aggregatie met behulp van CASE binnen aggregatiefuncties (bijvoorbeeld, SUM(CASE WHEN ...)). Het probleem doet zich voor bij het combineren van filters, groeperingen en totalen: het is gemakkelijk om onjuiste totalen te krijgen of het resultaat verkeerd te interpreteren.
Oplossing: gebruik voorwaardelijke aggregatie binnen aggregatiefuncties. Bijvoorbeeld, je moet het aantal "in behandeling" en "voltooid" bestellingen per werknemer weergeven:
SELECT employee_id, SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) as processing_count, SUM(CASE WHEN status = 'done' THEN 1 ELSE 0 END) as done_count FROM Orders GROUP BY employee_id;
Belangrijke kenmerken:
Wat gebeurt er als de CASE-omschrijving NULL in plaats van 0 retourneert?
De aggregatiefunctie SUM negeert NULL. Daarom, als je CASE WHEN ... THEN 1 END schrijft, worden de gemiste rijen niet meegerekend. Het is beter om altijd expliciet ELSE 0 in te stellen.
SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END)
Kan een WHERE-filter de uiteindelijke som van de statussen wijzigen bij voorwaardelijke aggregatie?
Ja: als de hoofd WHERE de selectie beperkt (bijvoorbeeld, WHERE region = 'west'), dan zullen de berekeningen alleen worden uitgevoerd op de gefilterde gegevens. Voor globale totalen gebruik je een subquery of verwijder je de filter.
Kan HAVING worden gebruikt om rijen vóór groepering te filteren?
Nee. HAVING filtert al gegroepeerde gegevens op aggregaten. Filtering van de oorspronkelijke rijen gebeurt via WHERE.
In een analytisch rapport gebruikten we:
SUM(CASE WHEN status = 'approved' THEN 1 END)
Er waren veel NULL's, de uiteindelijke totalen waren verlaagd. Door de WHERE-filter gingen sommige benodigde rijen verloren.
Voordelen:
Nadelen:
We gebruikten:
SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END)
De code werd onderhouden in één enkele query, filters op het totaal - via HAVING.
Voordelen:
Nadelen: