ProgrammazioneAnalista SQL

Spiegare le differenze tra HAVING e WHERE in SQL. A cosa serve ciascuno di essi, come interagiscono con le funzioni aggregate e come evitare errori comuni nel loro utilizzo?

Supera i colloqui con l'assistente IA Hintsage

Risposta

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.

  • WHERE: non è possibile utilizzare funzioni aggregate (SUM, AVG, ecc.), poiché il filtraggio avviene PRIMA dell'aggregazione.
  • HAVING: è possibile utilizzare funzioni aggregate, poiché il filtraggio viene effettuato DOPO l'aggregazione.

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:

  • WHERE status = 'active' rimuoverà i licenziati prima del calcolo dei totali per dipartimento;
  • HAVING SUM(salary) > 50000 mostrerà solo quei dipartimenti dove lo stipendio totale supera i 50000.

Domanda trabocchetto

È 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;

Esempi di errori reali dovuti alla mancanza di conoscenza delle sfumature dell'argomento


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.