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

Come usare CASE in SQL

Se avete bisogno di valutare più dichiarazioni condizionali, l'istruzione SQL CASE fa al caso vostro. Ecco cosa dovete sapere per usare CASE come un professionista.

Perché CASE è così importante in SQL? Se state analizzando o manipolando dei dati, spesso vorrete definire delle regole basate su determinate condizioni, ad esempio se le prestazioni di un dipendente sono superiori alla media, dategli un aumento del 10%; se sono eccellenti, dategli un aumento del 15%; altrimenti, dategli un aumento del 5%.

Per gestire situazioni in cui è necessario valutare più affermazioni condizionali insieme e restituire i risultati a seconda di quale affermazione è vera, SQL offre l'istruzione CASE.

L'istruzione SQL CASE è uno dei costrutti condizionali più utili e ha molte applicazioni per l'analisi dei dati con SQL.

Se volete conoscere le applicazioni pratiche dell'istruzione CASE e i diversi modi per utilizzarla, questo articolo fa per voi.

Che cos'è l'istruzione CASE?

In SQL, l'istruzione CASE restituisce risultati basati sulla valutazione di determinate condizioni. È piuttosto versatile e può essere utilizzata in diversi costrutti. Ad esempio, può essere utilizzata per visualizzare i valori, ordinare i risultati dell'ordinamento o filtrare i record. Valuta le condizioni dichiarate e restituisce il risultato della prima affermazione che risulta vera.

Prima di entrare nel dettaglio del funzionamento di CASE, date un'occhiata alla sintassi dell'istruzione CASE:

CASE
WHEN <condition> THEN <value>,
WHEN <other condition> THEN <value>
ELSE <value>
END AS <column name>

Vediamo un esempio pratico di una semplice istruzione CASE.

Ecco la order_summary tabella:

order_idcustomer_idcustomer_namequantityorder_valueshipping_fee
A1231221Emily52059
A1243213Javier223000
A1253213Javier12320000
A1263213Javier1016000

Supponiamo di essere un analista di un'azienda di commercio elettronico. Volete analizzare gli ordini in base al loro valore e dividerli in fasce(molto bassa, bassa, media, alta e molto alta) in base al loro valore.

L'istruzione CASE può aiutare a raggiungere questo obiettivo. Ecco la query da scrivere:

SELECT  order_id,
	  CASE 
	  WHEN order_value <= 50 THEN 'Very Low'
  WHEN order_value > 50 AND order_value <= 200 THEN 'Low'
  WHEN order_value > 200 AND order_value <= 500 THEN 'Medium'
  WHEN order_value > 500 AND order_value <= 1000 THEN 'High'
  ELSE 'Very High' 
  END AS order_category
FROM    order_summary;

Ed ecco i risultati ottenuti:

order_idorder_category
A123Medium
A124Medium
A125Very High
A126High

In alternativa, è possibile utilizzare la query riportata di seguito:

SELECT order_id,
 CASE
 WHEN order_value <= 50 THEN 'Very Low'
 WHEN order_value <= 200 THEN 'Low'
 WHEN order_value <= 500 THEN 'Medium'
 WHEN order_value <= 1000 THEN 'High'
 ELSE 'Very High'
END AS order_category
FROM order_summary;

Si otterrà esattamente lo stesso risultato, poiché CASE smette di valutare un valore una volta che soddisfa i criteri di WHEN.

Ora, vediamo di scomporre queste query.

La prima parola chiave è SELECT, che specifica le colonne da restituire. Nel nostro caso, queste colonne erano order_id e order_category, che abbiamo usato come alias per l'istruzione CASE (CASE...END AS order_category).

L'istruzione CASE inizia con la parola chiave CASE. È seguita dalla parola chiave WHEN, dopo la quale si specifica una condizione da valutare (order_value <= 50). Questa è immediatamente seguita da THEN e dal valore di ritorno se la condizione è vera (‘Very Low’).

Ad esempio, prendiamo la prima istruzione:

CASE WHEN order_value <= 50 THEN 'Very Low'

In questa istruzione, quando il valore dell'ordine è inferiore o uguale a 50 dollari, viene restituito "Molto basso" come valore nella colonna order_category. In altre parole, classifichiamo tutti gli ordini con valore inferiore o uguale a 50 dollari nella categoria "Molto basso".

Se questa condizione non è vera (il valore è superiore a 50 dollari), la query controlla se il valore è superiore a 200 dollari. Se il valore è inferiore a 200 dollari ma superiore a 50 dollari, viene restituito "Low" come valore nella colonna order_category. Se il valore è superiore a 200 dollari, la query passa alla clausola successiva WHEN e così via.

Se nessuna delle condizioni risulta vera, viene restituito il valore specificato in ELSE. L'istruzione CASE aggiunge quindi una logica all'istruzione SELECT.

Se siete alle prime armi con SQL e volete capire come scrivere questo tipo di query, vi consiglio la traccia SQL from A to Z di LearnSQL.it. Inizia con le basi di SQL e dei database, per poi guidarvi fino a query e funzioni più sofisticate. È un ottimo modo per iniziare il viaggio in SQL.

Se si analizzano molti ordini, l'aggregazione può essere utile in query come queste. Aggregazione significa raggruppare record simili e poi utilizzare una metrica basata sui valori raggruppati per comprendere le caratteristiche di quel gruppo. In SQL, la clausola GROUP BY è l'ingresso nel mondo delle statistiche aggregate. (Per una comprensione più dettagliata di GROUP BY, consultate questo articolo).

Per ora vediamo come GROUP BY e CASE lavorano insieme. Ecco una versione aggiornata della nostra query precedente:

SELECT  CASE 
	  WHEN order_value <= 50 THEN 'Very Low'
  WHEN order_value > 50 AND order_value <= 200 THEN 'Low'
  WHEN order_value > 200 AND order_value <= 500 THEN 'Medium'
  WHEN order_value > 500 AND order_value <= 1000 THEN 'High'
  ELSE 'Very High' 
  END AS order_category,
  COUNT(order_id)
FROM    order_summary
GROUP BY 1;

E il nuovo risultato:

order_categoryCOUNT(order_id)
High1
Medium2
Very High1

Qui usiamo COUNT come funzione aggregata. Ecco come funziona. La clausola GROUP BY aggrega tutti i record in base ai valori restituiti nella prima colonna di SELECT. Nel nostro caso, si tratta di order_category.

Quindi, per ogni diverso valore di order_category, COUNT(order_id) calcolerà il numero totale di ordini appartenenti alla categoria corrispondente. L'istruzione CASE aiuta a decidere quale categoria assegnare a ciascun ordine. Nei nostri dati, abbiamo un totale di 1 ordine nella categoria "Alto" (order_value tra 500 e 1000), 2 ordini nella categoria "Medio" (order_value tra 200 e 500) e 1 ordine nella categoria "Molto alto" (order_value superiore a 1000).

In tutti gli esempi precedenti, l'istruzione CASE è stata utilizzata nella parte SELECT della query. Tuttavia, questa clausola è molto versatile e può essere utilizzata per restituire risultati basati su condizioni in altre parti della query.

Ora che avete un'idea di cosa sia l' istruzione CASE, vediamo altri modi per utilizzarla.

Uso di CASE nella clausola ORDER BY

La clausola ORDER BY viene utilizzata per ordinare i risultati di una query in un determinato ordine. Ad esempio, si potrebbe voler ordinare il numero di ordini effettuati da ciascun cliente in base a customer_name. Ecco la query da scrivere:

SELECT   customer_name,
   COUNT(order_id)
FROM 	   order_summary
GROUP BY customer_name
ORDER BY customer_name;

E l'output è:

customer_nameCOUNT(order_id)
Emily1
Javier3

In questo caso, la query ordina i risultati in ordine alfabetico crescente (perché si sta ordinando in base a un valore di testo). A meno che non si specifichi diversamente, ORDER BY utilizzerà sempre l'ordine ascendente (cioè A-Z, 1-10). È possibile inserire la parola chiave DESC dopo la clausola del nome della colonna per ordinare i risultati in ordine decrescente (Z-A, 10-1): ORDER BY customer_name DESC.

Si supponga di voler ordinare i record per order_id in ordine crescente. Tuttavia, si desidera mostrare prima gli ordini di oltre 120 elementi. In altre parole, si ordinerà prima per quantità di articoli (se la quantità è maggiore di 120) e poi per ID ordine. Ciò richiede una valutazione condizionale nella clausola ORDER BY:

Query:
SELECT
  customer_name,
  order_id,
  order_value,
  quantity
FROM
  order_summary
ORDER BY
  CASE WHEN quantity > 120 THEN quantity END, order_id;

Ecco il risultato:

customer_nameorder_idorder_valuequantity
JavierA1252000123
EmilyA1232055
JavierA12430022
JavierA126600101

In questa query, per prima cosa si ottengono le colonne customer_name, order_id, order_value e quantità dalla tabella. Nell'ordinare le righe, questa query ottiene prima le righe in cui la quantità è maggiore di 120. (In questo caso, la quantità è maggiore di 120). (Poiché non ci sono altre righe che soddisfano questo criterio, le altre righe vengono ordinate in base a order_id.

Uso di CASE nella clausola WHERE

La clausola WHERE viene utilizzata per filtrare i record dai risultati della query in base a condizioni dichiarate. Ad esempio, se l'azienda vuole rinunciare alle spese di spedizione per gli ordini superiori a 100 dollari, è possibile che si voglia prima vedere quanti ordini si qualificheranno e poi analizzarne l'impatto. La seguente clausola WHERE conterà solo gli ID degli ordini superiori a 100 dollari:

SELECT  COUNT(order_id)
FROM    order_summary
WHERE   order_value > 100;

E il risultato:

COUNT(order_id)
4

Sulla base del risultato, si può ipotizzare che circa 4 ordini saranno interessati da questa operazione. Naturalmente, questo è il primo passo dell'analisi; è probabile che si vogliano fare molte analisi più dettagliate per quantificare l'impatto.

Ora vi presento un esempio di utilizzo della clausola WHERE con CASE. Date un'occhiata alla influencer_list tabella:

influencer_nameinfluencer_channelyoutube_channelfb_channelmonth_yeartotal_views
LouisyoutubehungryLouisJan_20213200
JanetfacebookstylenmakeupJan_2021423444
MichaelfacebookInfl_brandXJan_20212322
MichaelfacebookInfl_brandXFeb_2021240000

Supponiamo che la vostra azienda utilizzi vari influencer per promuovere i vostri marchi. Volete vedere tutti gli influencer il cui canale YouTube o account Facebook utilizza direttamente il vostro nome ("BrandX").

Ogni influencer ha un tipo di canale/account. Ecco come scoprire quali menzionano il BrandX:

SELECT DISTINCT influencer_name
FROM influencer_list
WHERE CASE WHEN influencer_channel = 'facebook' THEN fb_channel
	     WHEN influencer_channel = 'youtube' THEN youtube_channel
	     END LIKE '%brandX%';

Ecco il risultato:

influencer_name
Michael

La query di cui sopra restituirà tutte le righe in cui youtube_channel o fb_channel contiene ‘brandX’. Come si fa? Si sa che WHERE e CASE WHEN lavorano insieme. Il nuovo elemento è LIKE '%brandX%'. LIKE è usato per far corrispondere il valore della colonna allo schema e il segno di percentuale (%) indica che qualsiasi numero di caratteri può essere anteposto o posposto a "BrandX" (ecco perché il % si trova alle due estremità di BrandX).

Uso di CASE nella clausola HAVING

La clausola HAVING viene utilizzata con la clausola GROUP BY per filtrare i gruppi visualizzati. Ad esempio, se si volessero visualizzare i record della tabella influencer_list in cui total_views nel corso della vita dell'influencer è superiore a un milione, si scriverà:

SELECT      influencer_name,
	   SUM(total_views)
FROM     influencer_list
GROUP BY influencer_name
HAVING   SUM(total_views) > 200000;

Ecco cosa si ottiene:

influencer_nameSUM(total_views)
Michael242322
Janet423444

Si può anche usare CASE con la clausola HAVING. Supponiamo di voler ottenere un elenco di influencer le cui visualizzazioni totali sono maggiori di 100 per YouTube o maggiori di 400.000 per Facebook.

SELECT      influencer_name,
	   influencer_channel,
	   SUM(total_views)
FROM     influencer_list
GROUP BY influencer_name,
	   influencer_channel
HAVING   CASE WHEN influencer_channel = 'youtube' 
        THEN SUM(total_views) > 100
  WHEN influencer_channel = 'facebook' 
  THEN SUM(total_views) > 400000
   END;

E il risultato:

influencer_nameinfluencer_channelSUM(total_views)
Louisyoutube3200
Janetfacebook423444

Questa query somma innanzitutto le visualizzazioni totali per influencer_name e influencer_channel. Nella clausola HAVING filtriamo quindi solo i gruppi che hanno più di 100 visualizzazioni per YouTube e più di 400.000 visualizzazioni per Facebook. Si noti che Michael, che ha 242.322 visualizzazioni su Facebook, non compare nell'output; il suo totale è inferiore a 400.000.

Utilizzo di CASE in un'istruzione UPDATE

È anche possibile utilizzare CASE in un' istruzione UPDATE. L'istruzione SQL UPDATE viene utilizzata per modificare i valori di una tabella esistente.

Immaginiamo di voler aggiornare i valori di influencer_channel nel nostro set di dati attuale cambiando i canali con un codice di due lettere: 'youtube' deve essere cambiato in 'yt' e 'facebook' deve essere cambiato in 'fb'.

UPDATE influencer_list
SET     influencer_channel = CASE influencer_channel 
 			  WHEN 'youtube' THEN 'yt'
			  WHEN 'facebook' THEN 'fb'
			  ELSE 'invalid value'
			  END;

Ecco come apparirà la tabella influencer_list dopo l'aggiornamento:

influencer_nameinfluencer_channelyoutube_channelfb_channelmonth_yeartotal_views
LouisythungryLouisJan_20213200
JanetfbstylenmakeupJan_2021423444
MichaelfbInfl_brandXJan_20212322
MichaelfbInfl_brandXFeb_2021240000

Si noterà che 'youtube' è stato sostituito con 'yt' e 'facebook' con 'fb' nella colonna influencer_channel.

È possibile utilizzare CASE anche per eliminare o inserire righe nelle tabelle. Per maggiori dettagli, leggete questo articolo sull'uso di CASE con le istruzioni di modifica dei dati.

Siete pronti a usare CASE nelle query SQL?

Dopo tutti questi esempi, sono sicuro che avete un'idea più precisa di come funziona CASE in SQL e delle varie applicazioni potenziali dell'istruzione. È quindi giunto il momento di mettere in pratica quanto appreso! Leggere di SQL vi aiuterà sicuramente a imparare, ma se volete diventare esperti, il mantra è "Pratica!".

Vi consiglio anche di seguire un buon corso pratico di SQL. Il corso di pratica di LearnSQL.it utilizza esempi pratici e casi d'uso, e non è necessario impostare nulla per iniziare: Internet e un browser sono sufficienti.

Più query scriverete, più diventerete bravi con CASE e gli altri comandi SQL. Perché aspettare? Iniziate subito!