GROUP BY wordt gebruikt om rijen te groeperen en gegevens te aggregeren, maar bij onjuist gebruik kan het ernstige fouten of suboptimale prestaties veroorzaken.
Belangrijke nuances:
Voorbeeld:
SELECT customer_id, COUNT(*) as orders FROM orders WHERE order_date >= '2024-01-01' GROUP BY customer_id HAVING COUNT(*) > 10;
Mag je in SELECT na GROUP BY verwijzen naar velden die niet zijn gespecificeerd in GROUP BY of in een aggregatiefunctie?
Antwoord: Nee, dit leidt tot een fout in de meeste SQL-implementaties (bijvoorbeeld in MS SQL, PostgreSQL). Sommige specifieke databases kunnen een willekeurige, onjuiste waarde tonen (vooral in MySQL met 'ONLY_FULL_GROUP_BY' in de uitgeschakelde modus), maar dit gedrag is niet correct en wordt niet door de standaard gegarandeerd. Correct voorbeeld:
SELECT department, AVG(salary) FROM employees GROUP BY department;
Verhaal
In een e-commerce project bereidde een rapport "omzet per product" een query voor met SELECT sku, price, SUM(qty) FROM orders GROUP BY sku. Niet opgemerkt: price werd niet opgenomen in GROUP BY en was buiten de aggregatiefunctie, het resultaat — MySQL gaf de eerste waarde terug die beschikbaar was, wat tijdens een actie ernstige fouten in het rapport veroorzaakte. Oplossing — voeg price toe aan GROUP BY of gebruik een aggregatiefunctie.
Verhaal
In een BI-project duurde een complexe rapportage met verschillende JOIN en GROUP BY 80 minuten in plaats van de geplande 3. Na analyse bleek dat er geen indexen waren voor het veld van GROUP BY en filtering, wat leidde tot enorme tijdelijke tabellen voor aggregatie. Oplossing — optimalisatie van indexen en herschrijven van de query met tabelexpressies.
Verhaal
De ontwikkelaar gebruikte HAVING voor het filteren van waarden op een niet-geaggregateerde gebruikersattribuut. Dit resulteerde erin dat de server de groepering over alle gegevens uitvoerde en daarna deze eruit haalde volgens HAVING, wat de prestaties verminderde. We hebben het opgelost — deze controle naar WHERE verplaatst om de selectie tot de aggregatie te beperken.