WHERE filtra le righe prima dell'esecuzione della aggregazione, cioè determina quali registrazioni entreranno nell'aggregazione. HAVING filtra i gruppi già dopo l'applicazione delle funzioni aggregate.
Esempio:
-- Ottenere i dipartimenti con uno stipendio totale superiore a 50000, escludendo i dipendenti licenziati SELECT department, SUM(salary) as total FROM employees WHERE status = 'active' GROUP BY department HAVING SUM(salary) > 50000;
Qui:
È possibile utilizzare funzioni aggregate in WHERE?
Errore: si cerca di scrivere WHERE SUM(amount) > 100, ma non è possibile: le funzioni aggregate possono essere utilizzate SOLO in HAVING.
Esempio (ERRATO):
SELECT customer_id, SUM(amount) FROM orders WHERE SUM(amount) > 100 GROUP BY customer_id -- ERROR: uso errato di SUM() in WHERE
Corretto:
SELECT customer_id, SUM(amount) FROM orders GROUP BY customer_id HAVING SUM(amount) > 100;
Storia
Sviluppo di CRM. Tentativo di filtrare i clienti con un numero di ordini >5 tramite WHERE COUNT(order_id) > 5. La query non funzionava. Risultato: il numero di clienti nel report era errato, poiché COUNT non può essere utilizzato in WHERE.
Storia
Analisi aziendale. Invece di filtrare i prodotti inattivi in WHERE, hanno utilizzato HAVING. Risultato: aggregazione di gruppi "vuoti" e SQL lento. Corretto spostando il filtraggio per stato in WHERE.
Storia
Report complesso. Utilizzo di HAVING senza GROUP BY per filtrare singole righe. In alcuni RDBMS ciò genera un errore, in altri un comportamento non ovvio. Conclusione: HAVING deve seguire l'aggregazione e le condizioni aggregate.