Istruzione SQL CASE WHEN: sintassi, esempi reali ed errori comuni

  1. Home
  2. Blog
  3. Database e SQL

Database e SQL

Istruzione SQL CASE WHEN: Sintassi, esempi reali ed errori comuni

CASE WHEN è il modo in cui scrivi la logica if-then in SQL. Impara entrambi i moduli, quindi utilizzali per etichette, report in stile pivot, ordinamento personalizzato e aggiornamenti sicuri, evitando il NULL e le trappole dell’ordinamento.

8 min di lettura
Istruzione SQL CASE WHEN: sintassi, esempi reali ed errori comuni

Punti chiave

  • CASE restituisce un valore basato sulla condizione primo che è vera.
  • Metti al primo posto le condizioni più specifiche, altrimenti quelle successive potrebbero non essere mai raggiunte.
  • Senza ELSE, le righe senza corrispondenza restituiscono NULL.
  • All’interno di SUM o COUNT, CASE trasforma una query in un report compatto in stile pivot.

La maggior parte dei report necessita di una certa logica: etichettare gli ordini come grandi o piccoli, contare gli ordini pagati e quelli in sospeso fianco a fianco o mostrare prima gli articoli urgenti. SQL CASE WHEN gestisce tutto questo direttamente all’interno di una query e funziona su tutti i principali database.

Abbiamo eseguito ogni query qui in SQLite 3.50 e i risultati mostrati provengono da quell’esecuzione. CASE fa parte di SQL standard, quindi si comporta allo stesso modo in PostgreSQL, MySQL, SQL Server e Oracle per questi esempi.

Cos’è CASO QUANDO?

CASE è un’espressione, non un comando separato. Valuta le condizioni in ordine e restituisce un valore, quindi può andare ovunque sia consentito un valore: in SELECT, WHERE, GROUP BY, ORDER BY o all’interno di funzioni. Termina sempre con END.

CASE
  WHEN condition1 THEN result1
  WHEN condition2 THEN result2
  ELSE fallback
END

La tabella dei campioni

CREATE TABLE orders (id INT, customer TEXT, total INT, status TEXT);

INSERT INTO orders VALUES
 (1,'Asha',1200,'paid'), (2,'Ben',300,'pending'),
 (3,'Asha',800,'paid'), (4,'Chitra',2500,'shipped'),
 (5,'Dev',150,'cancelled'), (6,'Ben',NULL,'pending');

Nota che l’ordine 6 non ha totale. Quella riga conta più tardi.

CASO cercato

Questa è la forma più flessibile, poiché ciascuno WHEN ha una propria condizione completa:

SELECT id, total,
       CASE
         WHEN total >= 1000 THEN 'large'
         WHEN total >= 500 THEN 'medium'
         ELSE 'small'
       END AS size
FROM orders;

-- 1 | 1200 | large
-- 2 |  300 | small
-- 3 |  800 | medium
-- 4 | 2500 | large
-- 5 |  150 | small
-- 6 | NULL | small

Guarda l’ultima riga. L’ordine 6 non ha un totale, ma è etichettato come “piccolo”. Entrambi i confronti con NULL non erano veri, quindi è passato a ELSE. Mostriamo come risolvere questo problema nella sezione NULL. Assegna sempre un nome al risultato utilizzando AS, altrimenti potresti ottenere un nome di colonna scomodo.

CASO semplice

Quando confronti una colonna con valori fissi, la forma più breve si legge meglio:

SELECT id,
       CASE status
         WHEN 'paid' THEN 'Complete'
         WHEN 'shipped' THEN 'Complete'
         WHEN 'pending' THEN 'Waiting'
       END AS label
FROM orders;

-- 1 | Complete
-- 2 | Waiting
-- 3 | Complete
-- 4 | Complete
-- 5 | NULL
-- 6 | Waiting
Modulo Confronta È possibile utilizzare gli intervalli? Meglio per
Semplice Un’espressione per l’uguaglianza No Mappatura dei codici sulle etichette
Cercato Qualsiasi condizione per ramo Sì Intervalli, colonne multiple, controlli NULL

L’ordine conta

CASE si ferma alla prima condizione vera e questo è il bug logico più comune. Scambia le due condizioni della nostra query precedente:

SELECT id, total,
       CASE
         WHEN total >= 500 THEN 'medium'
         WHEN total >= 1000 THEN 'large'
         ELSE 'small'
       END AS size
FROM orders WHERE id IN (1, 4);

-- 1 | 1200 | medium
-- 4 | 2500 | medium

Ormai nulla potrà mai essere “grande”. Un totale di 2500 è anche almeno 500, quindi vince il primo ramo e il secondo non viene mai raggiunto. Non viene visualizzato alcun errore, solo etichette errate. Per gli intervalli, metti prima la condizione più restrittiva oppure scrivi intervalli completi, come total >= 500 AND total < 1000.

Cosa succede senza ALTRO?

Nel nostro semplice esempio CASE sopra, l’ordine 5 è stato annullato e nessuna filiale lo ha gestito, quindi il risultato è stato NULL. A volte è esattamente quello che vuoi, come mostra la sezione successiva. Ma quando si creano etichette, un chiaro ELSE 'other' è solitamente migliore, poiché rende visibili i valori inaspettati anziché lasciare spazi vuoti in un report.

Suggerimento: tutti i rami dovrebbero restituire lo stesso tipo. La combinazione di testo e numeri funziona in modo approssimativo in SQLite, ma database più rigidi, come PostgreSQL, genereranno un errore o proveranno a convertire i valori in modi non previsti.

Rapporti in stile pivot con SUM

Questo è uno dei modelli più utili nell’SQL quotidiano. Il confezionamento di CASE in un aggregato trasforma le righe in colonne, con una riga per cliente:

SELECT customer,
       SUM(CASE WHEN status = 'paid' THEN total ELSE 0 END) AS paid,
       SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending_orders
FROM orders
GROUP BY customer
ORDER BY customer;

-- Asha   | 2000 | 0
-- Ben    |    0 | 2
-- Chitra |    0 | 0
-- Dev    |    0 | 0

Una query ora fornisce sia le entrate pagate che il numero di ordini in sospeso, senza la necessità di query o unioni separate. Il modello funziona in quasi tutti i database, a differenza della sintassi dedicata PIVOT che solo alcuni offrono. Se GROUP BY è nuovo per te, leggi SQL GROUP BY e HAVING.

Conteggi condizionali

COUNT salta i NULL, quindi un CASE senza ELSE conta solo le righe che corrispondono:

SELECT COUNT(*) AS all_orders,
       COUNT(CASE WHEN status = 'paid' THEN 1 END) AS paid_orders,
       COUNT(CASE WHEN total >= 1000 THEN 1 END) AS large_orders
FROM orders;

-- 6 | 2 | 2

Fai attenzione: se aggiungi ELSE 0 all’interno di un COUNT, ogni riga viene conteggiata, perché 0 non è NULL. Usa ELSE 0 con SUM e lascialo fuori con COUNT. PostgreSQL e SQLite supportano anche COUNT(*) FILTER (WHERE ...), che si legge bene, ma non è disponibile ovunque.

Raggruppamento per CASO

Puoi creare i tuoi bucket e poi riassumerli:

SELECT CASE WHEN total >= 1000 THEN 'large' ELSE 'other' END AS bucket,
       COUNT(*)
FROM orders
GROUP BY bucket
ORDER BY bucket;

-- large | 2
-- other | 4

Il raggruppamento per alias funziona in SQLite, PostgreSQL e MySQL. SQL Server non lo consente, quindi dovresti ripetere l’intera espressione o inserire prima la query in un CTE o in una sottoquery.

Ordinamento personalizzato con ORDER BY

L’ordine alfabetico è raramente ciò che un’azienda desidera. CASE ti consente di definire il tuo ordine:

SELECT id, status FROM orders
ORDER BY CASE status
           WHEN 'pending' THEN 1
           WHEN 'paid' THEN 2
           ELSE 3
         END, id;

-- 2 | pending
-- 6 | pending
-- 1 | paid
-- 3 | paid
-- 4 | shipped
-- 5 | cancelled

Gli ordini in sospeso vengono prima, il che è utile per una coda di lavoro. La seconda colonna di ordinamento, id, mantiene le righe in un ordine prevedibile all’interno di ciascun gruppo.

CASO in AGGIORNAMENTO

CASE consente a un’istruzione di applicare modifiche diverse a righe diverse. Qui, i piccoli ordini in sospeso vengono contrassegnati per la revisione:

UPDATE orders
SET status = CASE
               WHEN status = 'pending' AND total < 500 THEN 'review'
               ELSE status
             END;

SELECT id, status FROM orders WHERE customer = 'Ben';

-- 2 | review
-- 6 | pending

Il ELSE status mantiene invariate le altre righe. Tralasciarlo è pericoloso, perché le righe senza corrispondenza verrebbero impostate su NULL. Senza una clausola WHERE questa istruzione tocca anche ogni riga, quindi su tabelle di grandi dimensioni aggiungi un filtro e considera di racchiudere la modifica in una transazione in modo da poter controllare il risultato prima di impegnarti. Si noti inoltre che l’ordine 6 non è cambiato, perché il suo totale NULL non soddisfaceva total < 500.

Trappole NULL

NULL causa due problemi separati con CASE. Innanzitutto, la forma semplice confronta utilizzando l’uguaglianza e nulla è uguale a NULL, nemmeno lo stesso NULL:

SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'not matched' END;

-- not matched

Quindi CASE col WHEN NULL non corrisponde mai. Utilizzare invece il modulo cercato con IS NULL. In secondo luogo, come abbiamo visto con l’ordine 6, un valore NULL supera i confronti e finisce in ELSE. La soluzione è verificarlo prima:

SELECT id,
       CASE
         WHEN total IS NULL THEN 'unknown'
         WHEN total >= 1000 THEN 'large'
         ELSE 'other'
       END AS size
FROM orders WHERE id IN (1, 2, 6);

-- 1 | large
-- 2 | other
-- 6 | unknown

L’ordine 6 ora ottiene un’etichetta onesta. La nostra guida ai valori NULL SQL copre questo comportamento in modo completo.

CASO rispetto ad altre opzioni

Opzione Funziona dentro Usalo quando
CASO Tutti i principali database Vuoi una logica portatile
COALESCE Tutti i principali database Hai solo bisogno di un fallback per NULL
IF() MySQL Una semplice scelta a doppio senso
IIF() SQL Server, SQLite Una semplice scelta a doppio senso
DECODE() Oracolo Codice Oracle precedente
Tabella di ricerca Tutto La mappatura è lunga o cambia spesso

Quest’ultima opzione merita una riflessione. Se un CASO cresce fino a trenta rami e appare in cinque query, sposta la mappatura in una tabella e unisciti ad essa. Quindi una modifica è un aggiornamento di una singola riga, anziché una modifica del codice in cinque punti.

Errori comuni

  • Ordine delle condizioni errato. Una condizione ampia nasconde prima quelle più ristrette.
  • Dimenticare END. Questo è l’errore di sintassi più frequente.
  • Utilizzando WHEN NULL. Non corrisponde mai, quindi utilizza WHEN col IS NULL.
  • Aggiungendo ELSE 0 all’interno di COUNT. Conta tutte le righe.
  • Omissione di ELSE in un UPDATE. Può cancellare i valori con NULL.
  • Filtro per CASE in WHERE. Può impedire l’utilizzo di un indice. Consulta la nostra guida all’ottimizzazione delle query SQL.

Considerazioni finali

CASE WHEN è una piccola funzionalità che fa molto lavoro. Ricorda tre regole: vince il primo ramo vero, le righe senza corrispondenza diventano NULL senza ELSE e NULL necessita del proprio controllo. Per esercitarti, prendi un report che attualmente crei con diverse query e prova a produrlo come un’unica query utilizzando SUM(CASE ...).

Domande frequenti

Cosa fa CASE WHEN in SQL?

Aggiunge la logica if-then a una query. SQL controlla ciascuna condizione in ordine e restituisce il valore della prima che è vera o il valore ELSE se non lo è.

Cosa succede se non c’è ELSE in un’istruzione CASE?

Le righe che non soddisfano alcuna condizione restituiscono NULL. Ciò è utile all’interno di COUNT, ma nelle etichette e negli aggiornamenti può causare spazi vuoti o perdita di dati.

Posso utilizzare CASE in una clausola WHERE?

Sì, perché è un’espressione. Tuttavia, le condizioni AND e OR semplici sono generalmente più chiare ed è più probabile che utilizzino un indice.

Qual è la differenza tra CASE semplice e CASE cercato?

CASE semplice confronta un’espressione con valori fissi per l’uguaglianza. CASE cercato ha una condizione completa in ogni WHEN, quindi può gestire intervalli e controlli NULL.

Le istruzioni CASE possono essere nidificate?

Sì, un CASO può apparire all’interno di un altro. Tuttavia, l’annidamento profondo diventa difficile da leggere, quindi valuta la possibilità di combinare le condizioni con AND o di utilizzare una tabella di ricerca.

Continua a imparare

Lavora con Stack Quora

Hai bisogno di aiuto con test, WordPress o SEO?

Aiutiamo i team a fornire software migliore e a far crescere i loro siti. Raccontaci a cosa stai lavorando e ti suggeriremo chiaramente il prossimo passo.

Continua a leggere

Altre guide su test, intelligenza artificiale e sviluppo moderno

Ti è piaciuto questo articolo? Scegli un argomento e passa direttamente ai nostri tutorial più recenti.

Intelligenza artificiale

Spiegazione delle allucinazioni dell'intelligenza artificiale: perché i modelli linguistici inventano le cose e come ridurle

Spiegazione delle allucinazioni dell'intelligenza artificiale: cosa sono, perché i modelli linguistici le producono, tipi comuni, come ridurle con b…

Leggi l'articolo →
DevOps

Spiegazione delle variabili d'ambiente: file .env, segreti e configurazione eseguiti correttamente

Variabili d'ambiente spiegate con esempi Python che abbiamo eseguito: lettura e impostazione, perché ogni valore è una stringa, file .env, ereditari…

Leggi l'articolo →
Sviluppo software

Spiegazione della limitazione della velocità API: algoritmi, intestazioni e gestione degli errori 429

La limitazione della velocità dell'API spiegata con una simulazione che abbiamo eseguito: bucket di token, finestra fissa, finestra scorrevole, risp…

Leggi l'articolo →
Automazione dei test

Derisione in Python: unittest.mock, patch e gli errori che fanno mentire i test

Mocking in Python con unittest.mock, testato: Mock e return_value, side_effect, patch dove viene utilizzato un nome, specifiche e autospec, date moc…

Leggi l'articolo →
Test del software

Spiegazione della copertura del codice: copertura di linea o di filiale e cosa significa realmente il 100%.

Copertura del codice spiegata con una vera esecuzione di cover.py: copertura di linea, ramo e condizione, lettura di un rapporto, perché la copertur…

Leggi l'articolo →
Database e SQL

DELETE vs TRUNCATE vs DROP in SQL: differenze, rollback e quando utilizzarli

DELETE vs TRUNCATE vs DROP spiegato con SQL testato: cosa rimuove, rollback, trigger, reimpostazione dell'identità, velocità e come differiscono Pos…

Leggi l'articolo →
Database e SQL

Spiegazione delle visualizzazioni SQL: crea, utilizza ed evita le insidie, con esempi

Viste SQL spiegate con le query che abbiamo eseguito: creazione di una vista, risultati in tempo reale, nascondere colonne, prestazioni, viste aggio…

Leggi l'articolo →
Sviluppo software

Interfaccia TypeScript e tipo: differenze reali, testate con il compilatore

Interfaccia TypeScript vs tipo, verificata con il vero compilatore: cosa possono fare entrambi, cosa può fare solo uno, fusione delle dichiarazioni,…

Leggi l'articolo →
Sviluppo software

Spiegazione di Python *args e **kwargs: funzioni flessibili con esempi chiari

Python *args e **kwargs spiegati con il codice che abbiamo eseguito: compressione e decompressione, ordine dei parametri, argomenti solo per parole …

Leggi l'articolo →
Sviluppo software

Funzioni Lambda Python: sintassi, usi reali e quando non usarli

Funzioni lambda Python spiegate con il codice che abbiamo eseguito: sintassi, ordinamento con chiave, mappa e filtro, chiusure, trap dell'associazio…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli agenti AI? Come funzionano, con un semplice ciclo di agenti che puoi eseguire

Cosa sono gli agenti IA? Una semplice guida al ciclo dell'agente, agli strumenti, alla memoria e ai guardrail, con un piccolo ciclo Python che abbia…

Leggi l'articolo →
DevOps

Monitoraggio vs osservabilità: la vera differenza, con log, metriche e tracce

Spiegazione del monitoraggio e dell'osservabilità: errori noti e sconosciuti, log, metriche e tracce, una procedura dettagliata sugli incidenti di p…

Leggi l'articolo →
DevOps

Volumi Docker e montaggi di associazione: mantenere i dati del contenitore nel modo giusto

Volumi Docker e montaggi di collegamento spiegati: perché i dati del contenitore scompaiono, volumi denominati, montaggi di collegamento, tmpfs, ese…

Leggi l'articolo →
Automazione dei test

TDD vs BDD: differenze chiave, una caratteristica costruita in entrambi i modi e quando utilizzarli ciascuno

TDD vs BDD spiegato con una funzione di sconto costruita in entrambi i modi: refactoring rosso-verde con il codice che abbiamo eseguito, scenari "Da…

Leggi l'articolo →
Test del software

Test di accettazione da parte dell'utente (UAT): processo, lista di controllo ed esempi reali

Spiegazione del test di accettazione dell'utente: chi lo esegue, in cosa differisce dal QA, un processo in sette fasi, un modello di test case UAT, …

Leggi l'articolo →
Database e SQL

Spiegazione dei valori SQL NULL: IS NULL, COALESCE, NULLIF e le trappole da evitare

Valori SQL NULL spiegati con le query che abbiamo eseguito: logica a tre valori, IS NULL, COALESCE, NULLIF, come aggregazioni, join e ordinamento tr…

Leggi l'articolo →
Database e SQL

Istruzione SQL CASE WHEN: sintassi, esempi reali ed errori comuni

SQL CASE WHEN spiegato con le query che abbiamo eseguito: moduli semplici e cercati, ordine delle condizioni, pivot con SUM, trucchi COUNT, ordiname…

Leggi l'articolo →
Sviluppo software

Cos'è il JWT? Token Web JSON spiegati con un esempio funzionante

Cos'è il JWT? Spiegazione dei token Web JSON: le tre parti, un token creato e manomesso nel codice che abbiamo eseguito, JWT e sessioni, archiviazio…

Leggi l'articolo →
Sviluppo software

Spiegazione del loop di eventi JavaScript: stack di chiamate, microtask e timer con esempi

Il ciclo di eventi JavaScript spiegato con il codice che abbiamo eseguito: stack di chiamate, code di attività e microtask, perché setTimeout 0 non …

Leggi l'articolo →
Sviluppo software

Spiegazione dei generatori Python e del rendimento: risparmia memoria con esempi reali

Generatori Python e rendimento spiegati con il codice che abbiamo eseguito: come vengono messi in pausa e ripresi, misurato il risparmio di memoria,…

Leggi l'articolo →
Intelligenza artificiale

Cosa sono gli incorporamenti? I vettori e la somiglianza del coseno spiegati semplicemente

Cosa sono gli incorporamenti? Una guida in linguaggio semplice ai vettori, alla similarità del coseno e alla ricerca semantica, con un piccolo esemp…

Leggi l'articolo →
DevOps

Distribuzione blu-verde rispetto a quella canaria: differenze, compromessi e come scegliere

Spiegazione della distribuzione blu-verde e canary: come funziona ciascuna, costi, rischi e rollback, bucket utente stabile che abbiamo testato, mig…

Leggi l'articolo →
Automazione dei test

Test instabili: quali sono le cause e come risolverli definitivamente

Test instabili spiegati con demo che abbiamo eseguito: le cause principali, come confermarne e diagnosticarne uno, soluzioni adeguate per tempistich…

Leggi l'articolo →
Test del software

Test di carico e test di stress: differenze, metriche ed esempi k6

Spiegazione del test di carico e dello stress test: cosa dimostra ciascuno, test di picco e di assorbimento, le metriche che contano, perché le medi…

Leggi l'articolo →
Test del software

Caso di test e scenario di test: differenze chiave, esempi e quando utilizzarli

Spiegazione del caso di test e dello scenario di test: definizioni chiare, una tabella affiancata, una funzione di reimpostazione della password pre…

Leggi l'articolo →
Database e SQL

Ottimizzazione delle query SQL: leggi i piani di esecuzione e correggi query lente, con tempistiche

Ottimizzazione delle query SQL testata su un milione di righe: leggi i piani di esecuzione, aggiungi gli indici corretti, correggi filtri non aggior…

Leggi l'articolo →
Database e SQL

SQL UNION vs UNION ALL: differenze, esempi e prestazioni testate

SQL UNION vs UNION ALL spiegati con le query che abbiamo eseguito: duplicati, regole seguite da entrambi, un vero bug di dati, prestazioni misurate,…

Leggi l'articolo →
Sviluppo software

Tutorial sull'API di recupero JavaScript: GET, POST, gestione degli errori e timeout

Un tutorial sull'API JavaScript Fetch testato su un server locale: GET e POST, perché 404 non genera eccezioni, un helper riutilizzabile, stringhe d…

Leggi l'articolo →
Sviluppo software

Gestione dei file Python: lettura, scrittura, CSV, JSON e pathlib con esempi

Gestione dei file Python spiegata con il codice che abbiamo eseguito: modalità aperte, con, lettura di file di grandi dimensioni, CSV, JSON, pathlib…

Leggi l'articolo →
Sviluppo software

Classi e oggetti Python: tutorial OOP con esempi reali

Classi e oggetti Python spiegati con il codice che abbiamo eseguito: __init__, metodi, attributi di classe e istanza, ereditarietà, proprietà, metod…

Leggi l'articolo →
Intelligenza artificiale

Che cos'è un modello linguistico di grandi dimensioni? Come funzionano i LLM, spiegato senza esagerazioni

Cos’è un modello linguistico ampio? LLM spiegati in un linguaggio semplice: token, incorporamenti, attenzione, formazione, finestre di temperatura e…

Leggi l'articolo →
DevOps

Comandi Linux per principianti: la guida essenziale del terminale con esempi

Comandi Linux per principianti, raggruppati per attività: navigazione, file, visualizzazione log, grep, pipe, permessi, processi e archivi, con un e…

Leggi l'articolo →
Sviluppo software

Git merge vs rebase: differenze, esempi e quando usare ciascuno

Git merge vs rebase spiegato con output reale del log, una tabella di confronto, la regola d'oro del rebase e un flusso di lavoro sicuro per i team.

Leggi l'articolo →
Sviluppo software

List comprehension in Python: sintassi, esempi e quando evitarla

List comprehension in Python spiegata: sintassi, filtri, if-else, cicli annidati, tempi misurati e i casi in cui un normale ciclo for è meglio.

Leggi l'articolo →
Database e SQL

SQL JOIN spiegati con esempi (Inner, Left, Right, Full)

Capisci i JOIN SQL passo dopo passo con tabelle e query di esempio: INNER, LEFT, RIGHT, FULL, CROSS e SELF, con errori comuni e consigli sulle prest…

Leggi l'articolo →