🧚 Ascolta! Beekeeper Studio è una GUI per database veloce, moderna e open source Scarica
13 gennaio 2026 Di Matthew Rathbone

CASE aggiunge la logica if/then/else a una query SQL: controlla una lista di condizioni e restituisce il risultato della prima che è vera. Gli esempi funzionano in PostgreSQL, MySQL, SQLite e SQL Server.

Come usare CASE

Elenca le coppie WHEN condition THEN result tra CASE e END. CASE restituisce il risultato della prima condizione vera, oppure il valore di ELSE se nessuna lo è:

CASE
  WHEN condition THEN result
  [WHEN condition THEN result ...]
  [ELSE result]
END
SELECT
  CASE
    WHEN 72 >= 90 THEN 'Hot'
    WHEN 72 >= 60 THEN 'Mild'
    ELSE 'Cold'
  END;
-- Output: Mild

Quando ogni condizione verifica l'uguaglianza con lo stesso valore, la forma “semplice”, più breve, indica quel valore una sola volta:

SELECT
  CASE 'amber'
    WHEN 'green' THEN 'Go'
    WHEN 'amber' THEN 'Slow down'
    WHEN 'red' THEN 'Stop'
    ELSE 'Unknown'
  END;
-- Output: Slow down

In una query reale le condizioni verificano le colonne, e CASE aggiunge una nuova colonna al risultato:

-- Input: orders
-- order_id | amount
-- ---------+--------
-- 1001     | 45.00
-- 1002     | 100.00
-- 1003     | 349.99
-- 1004     | 1250.00

SELECT
  order_id,
  amount,
  CASE
    WHEN amount < 100 THEN 'Small'
    WHEN amount < 500 THEN 'Medium'
    ELSE 'Large'
  END AS order_size
FROM orders;

-- Output:
-- order_id | amount  | order_size
-- ---------+---------+-----------
-- 1001     | 45.00   | Small
-- 1002     | 100.00  | Medium
-- 1003     | 349.99  | Medium
-- 1004     | 1250.00 | Large

Regole da conoscere

  • Vince la prima condizione vera. Le condizioni vengono controllate dall'alto verso il basso, quindi metti per prima la più restrittiva. Sopra, 100.00 è Medium perché amount < 100 è falso e amount < 500 è vero. Nell'ordine sbagliato, gli importi piccoli non raggiungono mai il loro ramo:
SELECT
  CASE
    WHEN 45 < 500 THEN 'Medium'
    WHEN 45 < 100 THEN 'Small'  -- can never win
    ELSE 'Large'
  END;
-- Output: Medium
  • Senza ELSE, se nulla corrisponde ottieni NULL.
SELECT CASE WHEN 72 >= 90 THEN 'Hot' END;
-- Output: NULL
  • Verifica NULL con IS NULL. NULL = NULL non è vero, quindi la forma semplice non può trovare un NULL. Usa la forma con condizioni:
SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'no match' END;
-- Output: no match

SELECT CASE WHEN NULL IS NULL THEN 'matched' ELSE 'no match' END;
-- Output: matched
  • Ogni risultato deve avere un tipo compatibile. Mescolare un numero e del testo nello stesso CASE dà errore in PostgreSQL e SQL Server, quindi converti il numero:
-- Input: products
-- name         | stock
-- -------------+------
-- Desk Lamp    | 12
-- Office Chair | 0

SELECT name, CASE WHEN stock > 0 THEN stock ELSE 'Sold out' END AS stock
FROM products;
-- PostgreSQL: ERROR: invalid input syntax for type integer: "Sold out"
-- SQL Server: Conversion failed when converting the varchar value 'Sold out' to data type int.

-- (in MySQL, cast with CAST(stock AS CHAR))
SELECT
  name,
  CASE WHEN stock > 0 THEN CAST(stock AS VARCHAR(10)) ELSE 'Sold out' END AS stock
FROM products;

-- Output:
-- name         | stock
-- -------------+---------
-- Desk Lamp    | 12
-- Office Chair | Sold out

Sintassi alternativa

Per una singola condizione, troverai anche una funzione più breve:

-- MySQL
SELECT IF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild

-- SQL Server and SQLite
SELECT IIF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild

Altre due funzioni sono abbreviazioni di espressioni CASE comuni. COALESCE(nickname, name) equivale a CASE WHEN nickname IS NOT NULL THEN nickname ELSE name END, e NULLIF(a, b) equivale a CASE WHEN a = b THEN NULL ELSE a END. Per la prima, leggi la guida a SQL COALESCE.

MySQL ha anche un'istruzione CASE per le stored procedure, che termina con END CASE. Questo articolo tratta l'espressione CASE che usi nelle query.

Quando usare CASE?

CASE è un'espressione, quindi funziona ovunque possa stare un valore: nella lista del SELECT, in ORDER BY e GROUP BY e dentro le funzioni di aggregazione. Funziona anche in WHERE, ma lì AND e OR di solito sono più chiari. La maggior parte degli usi rientra in uno di questi cinque.

Suddividere i numeri in fasce

Trasforma un numero in una fascia: livelli di prezzo, dimensioni degli ordini, fasce d'età, voti. Scrivi le condizioni da un estremo all'altro della scala, così la prima corrispondenza è quella giusta.

Tradurre codici in etichette

I database memorizzano codici brevi come 'A', 'ENG' o 'gold'; le persone vogliono parole. Un CASE semplice associa ogni codice a un'etichetta, o a un valore come una percentuale di sconto, ed ELSE cattura qualsiasi codice inatteso.

Contare o sommare solo alcune righe

Metti CASE dentro COUNT o SUM per contare o sommare solo le righe che soddisfano una condizione. COUNT(CASE WHEN ... THEN 1 END) funziona perché le righe senza corrispondenza danno NULL, che COUNT ignora. Un'aggregazione per condizione ti dà più totali affiancati: è così che si costruisce una tabella pivot in SQL.

Gestire i valori mancanti

Controlla le colonne per NULL in ordine di preferenza e restituisci un'etichetta quando sono tutte vuote. Per un semplice valore di ripiego, COALESCE è più breve. CASE è lo strumento giusto quando ogni tipo di lacuna richiede un risultato diverso.

Ordinare in modo personalizzato

L'ordine alfabetico e numerico non va bene per tutto: taglie di abbigliamento, priorità dei ticket, una lista con i prodotti in evidenza in cima. Un CASE in ORDER BY assegna a ogni valore la posizione che vuoi.

Esempi reali di CASE

Classificare i prodotti per reparto e prezzo

Un risultato può essere a sua volta un CASE, così ogni reparto ha le sue fasce di prezzo:

-- Input: products
-- product_name     | category    | price
-- -----------------+-------------+--------
-- Laptop Pro 14    | Electronics | 1499.00
-- Wireless Earbuds | Electronics | 129.00
-- Leather Jacket   | Clothing    | 349.00
-- Cotton T-Shirt   | Clothing    | 19.99
-- Coffee Mug       | Kitchen     | 12.50

SELECT
  product_name,
  CASE category
    WHEN 'Electronics' THEN
      CASE
        WHEN price > 1000 THEN 'Premium Electronics'
        ELSE 'Standard Electronics'
      END
    WHEN 'Clothing' THEN
      CASE
        WHEN price > 200 THEN 'Designer Clothing'
        ELSE 'Regular Clothing'
      END
    ELSE 'Other Products'
  END AS product_class
FROM products;

-- Output:
-- product_name     | product_class
-- -----------------+---------------------
-- Laptop Pro 14    | Premium Electronics
-- Wireless Earbuds | Standard Electronics
-- Leather Jacket   | Designer Clothing
-- Cotton T-Shirt   | Regular Clothing
-- Coffee Mug       | Other Products

Oltre due livelli, i CASE annidati diventano difficili da leggere. Di solito è più chiara una tabella di lookup da unire con una join.

Applicare uno sconto in base al livello del cliente

Ogni codice di livello corrisponde a una percentuale di sconto, e i clienti senza livello non ne ricevono:

-- Input: customers
-- id | customer_name | tier
-- ---+---------------+-------
-- 1  | Maya Brooks   | gold
-- 2  | Leo Martin    | silver
-- 3  | Ava Kim       | bronze
-- 4  | Noah Price    | NULL

-- Input: orders
-- id  | customer_id | order_total
-- ----+-------------+------------
-- 101 | 1           | 200.00
-- 102 | 2           | 150.00
-- 103 | 3           | 80.00
-- 104 | 4           | 60.00

SELECT
  customer_name,
  order_total,
  ROUND(order_total * CASE tier
    WHEN 'gold' THEN 0.15
    WHEN 'silver' THEN 0.10
    WHEN 'bronze' THEN 0.05
    ELSE 0
  END, 2) AS discount
FROM customers c
JOIN orders o ON c.id = o.customer_id
ORDER BY o.id;

-- Output:
-- customer_name | order_total | discount
-- --------------+-------------+---------
-- Maya Brooks   | 200.00      | 30.00
-- Leo Martin    | 150.00      | 15.00
-- Ava Kim       | 80.00       | 4.00
-- Noah Price    | 60.00       | 0.00

Trasformare le vendite mensili in colonne

Un SUM(CASE ...) per mese trasforma le righe di vendita in una colonna per ogni mese:

-- Input: sales
-- product_category | sale_date  | amount
-- -----------------+------------+-------
-- Books            | 2026-01-12 | 40.00
-- Games            | 2026-01-20 | 60.00
-- Books            | 2026-02-03 | 25.00
-- Books            | 2026-03-15 | 30.00
-- Games            | 2026-03-28 | 75.00

SELECT
  product_category,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan_sales,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb_sales,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar_sales
FROM sales
GROUP BY product_category
ORDER BY product_category;

-- Output:
-- product_category | jan_sales | feb_sales | mar_sales
-- -----------------+-----------+-----------+----------
-- Books            | 40.00     | 25.00     | 30.00
-- Games            | 60.00     | 0         | 75.00

In SQL Server, usa MONTH(sale_date) = 1 al posto di EXTRACT; in SQLite, usa strftime('%m', sale_date) = '01'.

Distinguere i valori mancanti da quelli vuoti

I dati importati spesso contengono sia NULL sia stringhe vuote. CASE può etichettarli in modo che tu sappia cosa ripulire:

-- Input: users
-- id | middle_name
-- ---+------------
-- 1  | Rose
-- 2  |
-- 3  | NULL

SELECT
  id,
  CASE
    WHEN middle_name IS NULL THEN 'Missing'
    WHEN middle_name = '' THEN 'Empty'
    ELSE middle_name
  END AS middle_name
FROM users;

-- Output:
-- id | middle_name
-- ---+------------
-- 1  | Rose
-- 2  | Empty
-- 3  | Missing

Assegna a ogni categoria una posizione di ordinamento, poi ordina per nome al suo interno:

-- Input: products
-- product_name | category
-- -------------+------------
-- Wool Scarf   | Sale
-- Desk Lamp    | Featured
-- Bike Helmet  | Clearance
-- Smart Watch  | New Arrival
-- Air Fryer    | Featured

SELECT product_name, category
FROM products
ORDER BY
  CASE category
    WHEN 'Featured' THEN 1
    WHEN 'New Arrival' THEN 2
    WHEN 'Sale' THEN 3
    ELSE 4
  END,
  product_name;

-- Output:
-- product_name | category
-- -------------+------------
-- Air Fryer    | Featured
-- Desk Lamp    | Featured
-- Smart Watch  | New Arrival
-- Wool Scarf   | Sale
-- Bike Helmet  | Clearance

Approfondimenti su CASE

Su questo blog:

Documentazione ufficiale:

Beekeeper Studio è una GUI per database gratuita & open source

Il miglior strumento per query & editor SQL che abbia mai usato. Offre tutto ciò che mi serve per gestire il mio database. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio è veloce, intuitivo e facile da usare. Beekeeper supporta tantissimi database e funziona alla grande su Windows, Mac e Linux.

La versione Linux di Beekeeper è completa al 100%, senza tagli e senza compromessi sulle funzionalità.

Cosa dicono gli utenti di Beekeeper Studio

★★★★★
"Beekeeper Studio ha sostituito completamente il mio vecchio flusso di lavoro SQL. È veloce, intuitivo e rende di nuovo piacevole lavorare con i database."
— Alex K., Database Developer
★★★★★
"Ho provato molte GUI per database, ma Beekeeper trova l'equilibrio perfetto tra funzionalità e semplicità. Funziona e basta."
— Sarah M., Full Stack Engineer

Pronto a migliorare il tuo flusso di lavoro SQL?

download Scarica gratis