Torna all'elenco degli articoli Articoli
Tempo di lettura: 9 minuti

Che cos'è CASE in SQL?

SQL CASE è un'espressione molto utile che fornisce la logica if-else alle query SQL. È un argomento un po' più avanzato, ma vi servirà quando preparerete dei report: darà un valore enorme ai vostri progetti personali e professionali.

L'istruzione SQL CASE è uno strumento del flusso di controllo che consente di aggiungere la logica if-else a una query. In generale, è possibile utilizzare l'istruzione CASE ovunque sia possibile utilizzare un'espressione valida, ad esempio con le clausole SELECT, WHERE e GROUP BY.

L'espressione CASE passa attraverso ogni condizione e restituisce un valore quando la prima condizione è soddisfatta. Quando una condizione è vera, CASE restituisce il risultato indicato. Se nessuna condizione è vera, restituisce il valore della clausola ELSE. Se non c'è ELSE e nessuna condizione è vera, restituisce NULL.

Semplice esempio di SQL CASE

Ecco la sintassi dell'espressione SQL CASE:

CASE 
  		WHEN condition_1 THEN result_1
   		WHEN condition_2 THEN result_2
   		ELSE else_result
END 

In questa sintassi, l'espressione SQL CASE abbina il valore a condition_1 o condition_2. Se viene trovata una corrispondenza, l'istruzione restituisce il risultato corrispondente (result_1 se il valore corrisponde a condition_1 o result_2 se corrisponde a condition_2). Se il valore non corrisponde a nessuna delle due condizioni, viene restituito else_result. L'istruzione ELSE è opzionale e fornisce un modo per catturare i valori non specificati nelle istruzioni WHEN..THEN. Infine, ogni istruzione CASE deve terminare con la parola chiave END.

Il tipo di dati del risultato dell'istruzione SQL CASE dipende dal contesto in cui viene utilizzato. Ad esempio, se l'espressione CASE viene utilizzata con stringhe CHAR, il risultato viene restituito come stringa CHAR. Se l'espressione CASE viene utilizzata in un contesto numerico, restituisce il risultato come un numero intero, un decimale o un valore reale. La padronanza di questo potente strumento del flusso di controllo crea molte nuove opportunità per recuperare e visualizzare i dati in modi creativi, come mostrato in questo articolo sull'aggiunta di logica alla query SQL con CASE.

Applichiamo l'istruzione SQL CASE a un esempio pratico. Immaginiamo di avere un piccolo negozio di alimentari e di utilizzare una semplice tabella di database per tenere traccia delle scorte. La tabella stock contiene l'articolo, il prezzo dell'articolo e la quantità di quell'articolo attualmente in magazzino.

ItemPriceQuantity
Bread1.5923
Milk2.003
Coffee3.2987
Sugar0.790
Eggs2.2053
Apples1.9917

E se volessimo una semplice descrizione per accompagnare i nostri dati e fornire un contesto più ampio ai nostri report? Questo è facilmente realizzabile con CASE WHEN:

SELECT Item, Price,
       CASE 
   WHEN Price < 1.00 THEN 'Below $1.00'
	   WHEN Price >= 1.00 THEN 'Greater or Equal to $1.00'
       END AS 'Price Description'
  FROM stock

Per prima cosa, l'istruzione SELECT dichiara che vogliamo recuperare i dati dalle colonne Item e Price. Poi c'è la dichiarazione CASE. Quando Price è inferiore a 1,00, restituiamo la stringa 'Below $1.00'. Quando Price è maggiore o uguale a 1,00, vogliamo restituire la stringa "Maggiore o uguale a $1,00". Questo viene applicato a ogni valore di Price nella nostra tabella.

Specifichiamo anche che i valori restituiti dall'istruzione CASE WHEN devono essere in una colonna chiamata Descrizione del prezzo:

ItemPricePrice Description
Brea1.59Greater or Equal to $1.00
Milk2.00Greater or Equal to $1.00
Coffee3.29Greater or Equal to $1.00
Sugar0.79Below $1.00
Eggs2.20Greater or Equal to $1.00
Apples1.99Greater or Equal to $1.00

Ecco fatto! Per ogni riga in cui Price è inferiore a 1,00, viene restituita la stringa 'Below $1.00'. Per i valori di Price maggiori o uguali a 1,00, viene restituita la stringa "Maggiore o uguale a $1,00". I risultati sono mostrati nella colonna Descrizione del prezzo.

SQL CASE WHEN con ELSE

Se si utilizza ELSE, questa istruzione deve venire dopo ogni condizione CASE WHEN specificata. Supponiamo ora di voler classificare i diversi prezzi nella nostra tabella in 3 diverse categorie:

  • Articoli al di sotto di $1,00.
  • Articoli tra $1,00 e $3,00.
  • Articoli superiori a $3,00.

Utilizzeremo l'istruzione ELSE per gestire Price i valori superiori a 3,00:

SELECT Item, Price,
       CASE WHEN Price < 1.00 THEN 'Below $1.00'
	   WHEN Price >= 1.00 AND Price <= 3.00 THEN 'Between $1.00 and $3.00'
	   ELSE 'Above $3.00' 
       END AS 'Price Description'
  FROM stock

Il valore Price di ogni riga viene controllato per vedere se è uguale o inferiore a 1,00 o se è compreso tra 1,00 e 3,00. Se rientra in una di queste categorie, viene restituita la stringa corrispondente. Se Price non è inferiore a 3,00, si passa all'istruzione ELSE. L'istruzione ELSE restituisce la stringa "Above $3.00".

Ecco perché l'ordine delle istruzioni è importante. L'SQL valuta ogni CASE in ordine, raggiungendo infine l'ELSE se non sono state soddisfatte le condizioni.

ItemPricePrice Description
Bread1.59Between $1.00 and $3.00
Milk2.00Between $1.00 and $3.00
Coffee3.29Above $3.00
Sugar0.79Below $1.00
Eggs2.20Between $1.00 and $3.00
Apples1.99Between $1.00 and $3.00

Utilizzo di più CASI

Il motivo principale per cui si sceglie di utilizzare l'istruzione SQL CASE è che si vogliono valutare più condizioni. Si vuole eseguire una serie di controlli e trasformare i risultati in dati significativi, di solito sotto forma di report.

Supponiamo di voler generare un semplice report per la nostra tabella. stock tabella. Ci dirà se il livello delle scorte è alto, medio, basso o del tutto esaurito! Questo può essere facilmente ottenuto utilizzando CASE:

SELECT Item,
      CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low'
            WHEN Quantity > 20 AND Quantity <= 50 THEN 'Medium'
            WHEN Quantity > 50 THEN 'High'
            ELSE 'Out Of Stock' 
		END AS 'Stock Level'
  	FROM stock

Questo è l'esempio più complesso che abbiamo fatto finora. Vediamo di scomporre questa query SQL.

Il nostro risultato avrà due colonne. La prima colonna è Item, che stiamo selezionando esplicitamente:

SELECT Item

La seconda colonna è la colonna dei risultati generata dalle espressioni SQL CASE WHEN, che chiamiamo Stock Level:

END AS 'Stock Level'

Ora analizziamo le singole condizioni, nell'ordine in cui SQL le valuterebbe.

In primo luogo, SQL verifica se Quantity è maggiore di zero e minore o uguale a 20.

	CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low'

Se il risultato è vero, viene restituito 'Low' e inizia la valutazione della riga successiva.

Se il risultato è falso, il valutatore esamina l'istruzione CASE successiva:

WHEN Quantity > 20 AND Quantity <= 50 THEN 'Medium'

Quantity viene controllato nuovamente per vedere se il valore è maggiore di 20 e minore o uguale a 50, restituendo in tal caso la stringa "Medio". Se questa condizione non è soddisfatta, viene verificata la condizione successiva:

WHEN Quantity > 50 THEN 'High'

L'istruzione finale CASE verifica se il valore Quantity è maggiore di 50 e, in caso affermativo, restituisce la stringa 'High'.

C'è un'altra situazione che non è coperta dalle diverse istruzioni CASE. Cosa succede se Quantity di un particolare Item è 0? Guardate di nuovo le nostre istruzioni CASE, in particolare:

		CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low'
		

Controlliamo che Quantity sia maggiore di 0, cioè se fosse uguale a 0, questa condizione verrebbe valutata come falsa e il database continuerebbe a controllare le altre istruzioni CASE. Per questo motivo abbiamo incluso l'istruzione ELSE nella nostra query SQL:

ELSE 'Out Of Stock' 

Serve proprio a questo scenario. Se l'istruzione Quantity di una Item è 0, il valutatore SQL raggiungerà la nostra istruzione ELSE e restituirà "Out of Stock".

L'esecuzione di questa query produce il seguente risultato:

ItemStock Level
BreadMedium
MilkLow
CoffeeHigh
SugarOut Of Stock
EggsHigh
ApplesLow

Possiamo vedere che lo zucchero ha un valore di Quantity pari a 0, che lo fa apparire come "esaurito". Confrontate gli altri valori di Quantity nella nostra stock con il valore Stock Level mostrato, per essere sicuri di capire come funzionano le nostre istruzioni CASE.

Immaginate quanto sarebbe utile questo report se ci fossero centinaia di articoli. Un report del genere potrebbe essere inviato quotidianamente ai responsabili degli acquisti, consentendo loro di mantenere i livelli di scorte degli articoli più richiesti.

CASE con valori NULL

Quando si utilizza CASE, si possono notare valori NULL indesiderati nel set di risultati. Perché compaiono questi valori e quali azioni si possono intraprendere per rimuoverli? I valori NULL compaiono quando un valore non corrisponde a nessuna delle istruzioni CASE o ELSE dichiarate. Vediamo un esempio pratico che mostra come può essere restituito un valore NULL.

Immaginiamo di aver escluso l'istruzione ELSE dall'esempio precedente. Che impatto avrebbe sui risultati? Esaminiamo la query precedente, questa volta senza l'istruzione ELSE:

SELECT Item,
      CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low'
            WHEN Quantity > 20 AND Quantity <= 50 THEN 'Medium'
            WHEN Quantity > 50 THEN 'High'
		END AS 'Stock Level'
  	FROM stock

I risultati sarebbero questi. Prestate particolare attenzione al livello delle scorte di zucchero:

ItemStock Level
BreadMedium
MilkLow
CoffeeHigh
SugarNULL
EggsHigh
ApplesLow

Senza ELSE per gestire la situazione in cui Quantity è zero, la nostra query restituisce un NULL.

Se nei risultati di CASE WHEN compare un valore NULL indesiderato, è possibile che si verifichi uno scenario non coperto dalle condizioni di CASE WHEN e ELSE.

GROUP BY con CASE

Come già detto, è possibile utilizzare l'espressione SQL CASE con GROUP BY. Esaminiamo un esempio pratico.

Immaginiamo di voler raggruppare gli articoli in base al loro prezzo, visualizzando anche il prezzo minimo e massimo per i gruppi a basso e alto costo. Ciò richiede l'uso delle funzioni aggregate MIN() e MAX(). L'istruzione GROUP BY viene spesso utilizzata per raggruppare i dati risultanti in base a una o più colonne, e spesso proprio con le funzioni aggregate. Ecco un esempio di utilizzo di GROUP BY insieme alle funzioni aggregate, che potete leggere per maggiori informazioni. Analizziamo la query SQL qui sotto per mostrare come si può ottenere il risultato desiderato:

SELECT
CASE WHEN Price >= 2.00 THEN 'High Price Item'
WHEN Price > 0 AND Price < 2.00 THEN 'Low Price Item'
END AS PriceLevel,
Min(Price) as MinimumPrice,
Max(Price) as MaximumPrice

FROM stock
GROUP BY
CASE WHEN Price >= 2.00 THEN 'High Price Item'
WHEN Price > 0 AND Price < 2.00 THEN 'Low Price Item'

END

Per prima cosa, analizziamo l'istruzione CASE. È simile all'esempio precedente.

CASE WHEN Price >= 2.00 THEN 'High Price Item'
WHEN Price > 0 AND Price < 2.00 THEN 'Low Price Item'
END AS PriceLevel

Se Price è maggiore o uguale a 2,00, l'articolo viene classificato come articolo ad alto prezzo. Se Price è maggiore di 0 ma inferiore a 2,00, l'articolo è un articolo a basso prezzo. Questi valori stringa vengono quindi memorizzati e visualizzati nella colonna PriceLevel, come specificato dall'alias END AS.

Utilizziamo le funzioni di aggregazione MIN() e MAX() sulla colonna Price. In questo modo si ottengono i valori Price più bassi e più alti degli elementi della tabella.

Utilizziamo la clausola GROUP BY per applicare queste funzioni aggregate alle due categorie di prezzi alti e bassi. (Non preoccupatevi se tutto ciò sembra complicato; la padronanza di GROUP BY richiede molta pratica. Consultate la nostra traccia SQL Practice per esercizi interattivi che affinano la tecnica GROUP BY e altre abilità SQL).

L'esecuzione di questa query SQL restituisce il seguente insieme di risultati:

PriceLevelMinimumPriceMaximumPrice
High Price Item2.003.29
Low Price Item0.791.99

Questi sono esattamente i risultati che volevamo! Ora possiamo vedere chiaramente il prezzo minimo e massimo di ciascuna delle categorie di articoli definite nella nostra istruzione SQL CASE WHEN. Fate riferimento alla nostra stock e notate quali singoli articoli sono collegati ai valori mostrati per MinimumPrice e MaximumPrice. Se aggiungessimo un nuovo articolo alla nostra tabella che costa 4,00 dollari, il prezzo minimo e massimo sarebbe di 4,00 dollari. stock che costa 4,00 dollari, si vedrebbe che MaximumPrice dell'"Elemento di prezzo elevato" aumenta a 4,00.

SQL CASE e query complesse riutilizzabili

L'uso di SQL CASE consente di scrivere query complesse che eseguono una serie di azioni. Abbiamo appena mostrato come utilizzare CASE WHEN con SELECT. Come mostrato in questo articolo sull'uso di CASE con le istruzioni di modifica dei dati, CASE WHEN può essere utilizzato anche con INSERT, UPDATE e DELETE. In questo modo si ottengono query altamente riutilizzabili che possono essere implementate per report o applicazioni. Se siete interessati a imparare a creare report personalizzati di alto valore, vi consiglio il corso completo di LearnSQL.it sulla creazione di report SQL.