CodeGym /Corsi /SQL SELF /Espressioni condizionali: CASE WHEN ... THEN ... ELSE ......

Espressioni condizionali: CASE WHEN ... THEN ... ELSE ... END

SQL SELF
Livello 10 , Lezione 0
Disponibile

Probabilmente ti sei già imbattuto in espressioni condizionali nei linguaggi di programmazione: if-else, switch-case e robe simili. In SQL c'è uno strumento tutto suo per lavorare con le condizioni: l'espressione CASE. Ti permette di prendere decisioni direttamente nelle query: se la condizione è vera, fai una cosa, se non lo è — fanne un'altra.

La struttura CASE è particolarmente utile quando devi lavorare con dati che possono avere valori NULL. La sintassi è semplice, tipo bigino, guarda qui:

CASE
    WHEN condizione1 THEN risultato1
    WHEN condizione2 THEN risultato2
    ...
    ELSE risultato_predefinito
END

Ha senso, vero? "Se succede questo, fai quello, altrimenti fai qualcos'altro". Facile da ricordare: "WHEN — è il se, THEN — è cosa fare, ELSE — è cosa fare se niente va bene".

Esempio: classificazione dei prodotti

Immagina di avere una tabella products con una colonna price, e vuoi dividere i prodotti in gruppi in base al loro prezzo.

id name price
1 Magic Wand 120
2 Potion Set 45
3 Crystal Ball 75
4 Enchanted Map NULL
5 Broomstick 99
6 Spell Book 180
SELECT
    name AS product_name,
    price,
    CASE
        WHEN price IS NULL THEN 'Sconosciuto'
        WHEN price < 50 THEN 'Economico'
        WHEN price BETWEEN 50 AND 100 THEN 'Standard'
        ELSE 'Premium'
    END AS price_category
FROM products;

Cosa succede qui?

  1. Se il prezzo price del prodotto non è specificato NULL, mostriamo la categoria come 'Sconosciuto'.
  2. Se il prezzo è minore di 50, il prodotto è considerato economico 'Economico'.
  3. Se il prezzo è tra 50 e 100, va nella categoria 'Standard'.
  4. Tutto il resto — sono prodotti di fascia alta 'Premium'.

Ecco il risultato:

product_name price price_category
Magic Wand 120 Premium
Potion Set 45 Economico
Crystal Ball 75 Standard
Enchanted Map NULL Sconosciuto
Broomstick 99 Standard
Spell Book 180 Premium

SQL, come un mago, legge le righe della tabella products, le passa una a una e le classifica in modo furbo.

Lavorare con NULL in CASE WHEN

Capita spesso che nei dati ci siano valori mancanti (ciao, NULL), e bisogna sostituirli con qualcosa. Per esempio, abbiamo una tabella users con la colonna email, e per gli utenti senza email vogliamo mostrare 'Non specificato'.

user_id name email
1 Alex Lin alex@example.com
2 Maria Chi NULL
3 Anna Song anna@magic.com
4 Otto Art NULL
5 John Smith john@wizard.org
SELECT
    user_id,
    name,
    CASE
        WHEN email IS NULL THEN 'Non specificato'
        ELSE email
    END AS email_address
FROM users;
user_id name email_address
1 Alex Lin alex@example.com
2 Maria Chi Non specificato
3 Anna Song anna@magic.com
4 Otto Art Non specificato
5 John Smith john@wizard.org

Qui SQL fa un po' lo sciamano, rianimando le righe mezze vuote. Se manca l'email, la sostituisce con 'Non specificato'. Se c'è — la lascia così com'è.

Espressioni condizionali con i numeri

A volte non basta solo sostituire i valori, ma serve anche costruire una logica nuova. Per esempio, supponiamo di avere una tabella students con le colonne score (voto) e name.

name score
Alex Lin 95
Maria Chi 82
Anna Song 48
Otto Art NULL
John Smith 67
Zoe Black 30

Vogliamo valutare gli studenti come "Eccellente", "Passato" e "Bocciato", in base ai loro punti.

SELECT
    name AS student_name,
    score,
    CASE
        WHEN score IS NULL THEN 'Nessun voto'
        WHEN score >= 90 THEN 'Eccellente'
        WHEN score >= 50 THEN 'Passato'
        ELSE 'Bocciato'
    END AS performance_category
FROM students;
student_name score performance_category
Alex Lin 95 Eccellente
Maria Chi 82 Passato
Anna Song 48 Bocciato
Otto Art NULL Nessun voto
John Smith 67 Passato
Zoe Black 30 Bocciato

SQL distribuisce gentilmente gli studenti, come un esaminatore severo: 90 punti e oltre — solo "Eccellente", da 50 in su — "Passato". Se i punti non bastano... beh, hai capito.

Raggruppamento e gestione dei NULL

Lavorare con gruppi di dati — è un altro campo dove CASE WHEN dà il meglio. Immagina di avere una tabella orders, e vuoi contare il numero totale di ordini per stato, inclusi quelli con stato NULL.

order_id status
1 Completed
2 Pending
3 NULL
4 Shipped
5 Completed
6 NULL
7 Pending
8 Completed
9 Shipped
10 NULL
SELECT
    CASE
        WHEN status IS NULL THEN 'Nessuno stato'
        ELSE status
    END AS order_status,
    COUNT(*)
FROM orders
GROUP BY 
    CASE
        WHEN status IS NULL THEN 'Nessuno stato'
        ELSE status
    END;

Questa query gestisce con cura gli stati vuoti NULL e mette 'Nessuno stato' al loro posto, contando anche il numero totale di ordini in ogni gruppo. Ecco il risultato:

order_status count
Completed 3
Pending 2
Shipped 2
Nessuno stato 3

Casi pratici: "Trucchi" con CASE WHEN

Esempio 1: Ordinamento considerando i NULL

A volte i valori NULL devono essere mostrati o all'inizio o alla fine di una lista ordinata. Questo si usa spesso, ad esempio, nelle liste di task, dove i task prioritari devono stare in alto, e quelli senza priorità (NULL) in fondo.

task_id task_name priority
1 Fix bugs 1
2 Update documentation 3
3 Plan sprint NULL
4 Code review 2
5 Organize meeting NULL
6 Deploy release 1
SELECT
    task_name,
    priority,
    CASE
        WHEN priority IS NULL THEN 1
        ELSE 0
    END AS priority_sort
FROM tasks
ORDER BY priority_sort ASC, priority ASC;

Qui abbiamo aggiunto una colonna "virtuale" priority_sort, che mette i valori NULL in fondo a tutto, e gli altri li ordina in modo crescente.

task_name priority priority_sort
Deploy release 1 0
Fix bugs 1 0
Code review 2 0
Update documentation 3 0
Plan sprint NULL 1
Organize meeting NULL 1

Esempio 2: Calcoli considerando i NULL

Ora immagina che stiamo calcolando il totale di un ordine nella tabella orders, dove nella colonna discount lo sconto può essere NULL se non c'è.

order_id total_price discount
101 100 10
102 200 NULL
103 150 15
104 120 NULL
105 80 5

Qui dobbiamo sostituire NULL con 0, così il calcolo non si rompe.

SELECT 
    order_id,
    total_price,
    discount,
    total_price - 
    CASE
        WHEN discount IS NULL THEN 0
        ELSE discount
    END AS final_price
FROM orders;
order_id total_price discount final_price
101 100 10 90
102 200 NULL 200
103 150 15 135
104 120 NULL 120
105 80 5 75

Questo trucchetto magico con CASE ci fa stare tranquilli che NULL non rovinerà i calcoli matematici.

Per orderid = 101: discount = 10. finalprice = 100 - 10 = 90. Per orderid = 102: discount = NULL. CASE restituisce 0. finalprice = 200 - 0 = 200. Per orderid = 103: discount = 15. finalprice = 150 - 15 = 135. Per orderid = 104: discount = NULL. CASE restituisce 0. finalprice = 120 - 0 = 120. Per orderid = 105: discount = 5. finalprice = 80 - 5 = 75.

Esempio 3: Mostrare status utente personalizzati

Nella vita di tutti i giorni capita di dover mostrare lo stato di un utente (tipo "Attivo" o "In attesa") o segnalare che mancano dati. Per esempio, nella tabella users c'è la colonna last_login, dove si salva la data dell'ultimo accesso.

user_id name last_login
1 Alex Lin 2024-12-10
2 Maria Chi 2025-04-20
3 Anna Song NULL
4 Otto Art 2025-05-01
5 Liam Park 2025-05-25
SELECT
    user_id,
    name,
    CASE
        WHEN last_login IS NULL THEN 'Mai loggato'
        WHEN last_login < CURRENT_DATE - INTERVAL '30 days' THEN 'Inattivo'
        ELSE 'Attivo'
    END AS user_status
FROM users;

Con questa query il sistema admin prende vita: gli utenti senza accesso vengono chiamati "Mai loggato", quelli che non entrano da un po' sono "Inattivo". Gli altri sono attivi!

user_id name user_status
1 Alex Lin Inattivo
2 Maria Chi Inattivo
3 Anna Song Mai loggato
4 Otto Art Inattivo
5 Liam Park Attivo

Errori comuni e come evitarli

Dimenticare ELSE: Se non aggiungi ELSE, SQL ti restituisce semplicemente NULL se nessuna condizione è soddisfatta. Non sempre è quello che vuoi. Quindi meglio specificare sempre ELSE, anche se sei sicuro di aver coperto tutti i casi.

CASE
    WHEN condition THEN result
    -- ELSE 'Valore predefinito' -- non dimenticare!
END

Condizioni complesse senza parentesi: Se hai più condizioni complesse con AND, OR o NOT, usa sempre le parentesi. Senza di loro la tua query potrebbe "pensare" male.

CASE
    WHEN (column1 IS NOT NULL AND column2 > 5) THEN 'Valido'
    ELSE 'Non valido'
END

Lavorare con NULL: Ricorda che NULL non è mai uguale (=) a qualcosa. Per esempio:

CASE
    WHEN column = NULL THEN 'Nope!' -- Errore!
    WHEN column IS NULL THEN 'Corretto!' -- Questo sì che va bene.
END
2
Compito
SQL SELF, livello 10, lezione 0
Bloccato
Visualizzazione condizionale dei dati mancanti
Visualizzazione condizionale dei dati mancanti
2
Compito
SQL SELF, livello 10, lezione 0
Bloccato
Assegnazione di categorie in base ai valori numerici
Assegnazione di categorie in base ai valori numerici
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION