In questo articolo impara quando usare DOVE e AVERE. Entrambi svolgono funzioni simili, ma per scopi diversi!
Tutti gli esempi di questo articolo sono basati su Microsoft SQL Server Management Studio e il database AdventureWorks2012. È possibile iniziare a utilizzare questi strumenti gratuiti utilizzando la mia guida Per iniziare a utilizzare SQL Server.
Come fare dove e avere Differire?
Quando si lavora con SQL più avanzato può non essere chiaro quando ha senso usare un WHERE rispetto a una clausola HAVING.
Anche se sembra che entrambe le clausole facciano la stessa cosa, lo fanno in modi diversi. In effetti, le loro funzioni si completano a vicenda.
- Viene utilizzata una clausola WHERE per filtrare i record da un risultato. Il filtro si verifica prima di qualsiasi raggruppamento.
- Una clausola HAVING viene utilizzata per filtrare i valori da un gruppo.
Prima di andare oltre, esaminiamo il formato di un’istruzione SQL. È
SELECTFROMWHEREGROUP BYHAVING
Per aiutare a mantenere le cose dritte Mi piace pensare all’ordine di esecuzione delle istruzioni SQL dall’alto verso il basso. Ciò significa che la clausola WHERE viene prima applicata al risultato e quindi, le righe rimanenti riepilogate in base al GRUPPO PER.
Clausola WHERE
La clausola WHERE viene utilizzata per filtrare le righe dai risultati. Ad esempio
SELECT COUNT(SalesOrderID)FROM Sales.SalesOrderDetail
Restituisce 121.317 come conteggio, mentre la query
SELECT COUNT(SalesOrderID)FROM Sales.SalesOrderDetailWHERE UnitPrice > 200
Restituisce 48.159 come conteggio. Ciò è dovuto alla clausola WHERE che filtra i 73.158 SalesOrderDetails il cui prezzo unitario è inferiore o uguale a 200 dai risultati.
Clausola HAVING
La clausola HAVING viene utilizzata per filtrare i valori in un GRUPPO PER. Puoi usarli per filtrare gruppi come
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SalesOrderID > 50000
Ma il loro vero potere sta nella loro capacità di confrontare e filtrare in base ai risultati delle funzioni aggregate. Ad esempio, puoi selezionare tutti gli ordini per un totale superiore a $10,000
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000
Poiché la visibilità della clausola WHERE è una riga alla volta, non esiste un modo per valutare la SOMMA su tutti i SalesOrderID. La clausola HAVING viene valutata dopo la creazione del raggruppamento.
Combinando i due: WHERE e HAVING
Quando le istruzioni SQL hanno sia una clausola WHERE che una clausola HAVING, tieni presente che la clausola WHERE viene applicata prima, quindi i risultati raggruppati e, infine, i gruppi filtrati in base alla clausola HAVING.
In molti casi, è possibile inserire la condizione WHERE nella clausola HAVING, ad esempio
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000 AND SalesOrderID > 50000
Rispetto a
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailWHERE SalesOrderID > 50000GROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000
Se è possibile inserire la condizione dalla clausola where nella clausola having, allora perché preoccuparsi del WHERE? Posso semplicemente usare questa query?
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000 AND LineTotal > 10
In realtà quella query genera un errore. La colonna LineTotal non fa parte dell’elenco group by field né è il risultato di un totale aggregato.
Per essere valida la clausola having può confrontare solo i risultati delle funzioni aggregate o della parte di colonna del gruppo by.
Per essere valida la query deve essere riscritta come
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailWHERE LineTotal > 100GROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000
Per riassumere la differenza tra WHERE e HAVING:
- DOVE viene utilizzato per filtrare i record prima che si verifichino eventuali raggruppamenti.
- HAVING viene utilizzato per filtrare i valori dopo che sono stati gruppi. Solo le colonne o le espressioni del gruppo possono essere incluse nelle condizioni della clausola HAVING