In SQL Server, il CASE
di T-SQL expression è un'espressione scalare che restituisce un valore basato sulla logica condizionale. Valuta un elenco di condizioni e restituisce un valore, in base al risultato di tali condizioni..
In un certo senso, il CASE
di SQL Server l'espressione è simile a IF...ELSE
. Tuttavia, CASE
ti consente di verificare più condizioni, mentre IF...ELSE
no.
Inoltre, in SQL Server, IF...ELSE
è una parola chiave del linguaggio di controllo del flusso, mentre CASE
non è. Il CASE
non è possibile utilizzare l'espressione per controllare il flusso di esecuzione di istruzioni T-SQL, blocchi di istruzioni, funzioni definite dall'utente e procedure memorizzate.
Le 2 forme di espressione CASE
Esistono due forme di CASE
espressione in SQL Server:
- Semplice
CASE
espressione - Cercato
CASE
espressione
Questi sono spiegati con esempi di seguito.
Modulo 1 – L'espressione CASE semplice
Il semplice CASE
expression confronta un'espressione con un insieme di espressioni semplici per determinare il risultato.
Ecco un esempio di base per dimostrare come un CASE
l'espressione funziona in SQL Server.
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 'AAPL' THEN 'Apple'
WHEN 'FB' THEN 'Facebook'
WHEN 'V' THEN 'Visa'
ELSE 'Not in the portfolio'
END
Risultato:
+-----------+ | Company | |-----------| | Visa | +-----------+
In questo esempio, il mio CASE
espressione fa parte di un SELECT
dichiarazione. Verifica tre condizioni e ha un ELSE
per soddisfare tutto ciò che non è coperto dalle tre condizioni.
In questo caso, il ticker di borsa V
corrisponde al terzo WHEN
espressione e l'espressione fornita da THEN
viene restituito.
Per essere chiari, il vero CASE
l'espressione è questa parte:
CASE @stock_ticker
WHEN 'AAPL' THEN 'Apple'
WHEN 'FB' THEN 'Facebook'
WHEN 'MA' THEN 'Mastercard'
WHEN 'V' THEN 'Visa'
ELSE 'Not in the portfolio'
END
Quale CASE
fa è, controlla il valore di ogni WHEN
espressione contro l'espressione di input. Nel mio esempio, il @stock_ticker
variabile è l'espressione di input. Pertanto, sta verificando il valore di ogni WHEN
espressione contro @stock_ticker
variabile.
Quando/se trova una corrispondenza, restituisce l'espressione fornita da THEN
.
Il mio esempio usa tre WHEN
espressioni, ma poteva essere di più e poteva essere di meno, a seconda delle mie esigenze.
Modulo 2 – L'espressione CASE ricercata
Il CASE
cercato expression valuta un insieme di espressioni booleane per determinare il risultato.
Ecco un esempio di un CASE
cercato espressione.
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
ELSE 'Expensive'
END
Risultato:
+-----------------+ | Affordability | |-----------------| | Expensive | +-----------------+
Un CASE
cercato espressione non ha un'espressione di input come il semplice CASE
espressione.
Lo ricorderai nel nostro semplice CASE
espressione, è iniziato con CASE
@stock_ticker
, e quindi sapevamo che il WHEN
le espressioni stavano tutte valutando rispetto al valore di @stock_ticker
.
Con il CASE
cercato espressione, all'inizio non forniamo un'espressione di input in questo modo. Invece, ogni WHEN
expression include un'espressione booleana per la quale essere valutata.
Un esempio di database
Ecco un esempio che dimostra come il CASE
l'espressione può essere utilizzata all'interno di una query di database.
USE WideWorldImporters;
SELECT
CityName AS [City],
LatestRecordedPopulation AS [Population],
Size =
CASE
WHEN LatestRecordedPopulation < 2000000 THEN 'Small City'
WHEN LatestRecordedPopulation >= 2000000 AND LatestRecordedPopulation < 3000000 THEN 'Big City'
ELSE 'Really Big City'
END
FROM Application.Cities
WHERE LatestRecordedPopulation > 1000000;
Risultato:
+--------------+--------------+-----------------+ | City | Population | Size | |--------------+--------------+-----------------| | Brooklyn | 2565635 | Big City | | Chicago | 2695598 | Big City | | Dallas | 1197816 | Small City | | Houston | 2099451 | Big City | | Los Angeles | 3792621 | Really Big City | | Manhattan | 1619090 | Small City | | New York | 8175133 | Really Big City | | Philadelphia | 1526006 | Small City | | Phoenix | 1445632 | Small City | | Queens | 2272771 | Big City | | San Antonio | 1327407 | Small City | | San Diego | 1307402 | Small City | | The Bronx | 1408473 | Small City | +--------------+--------------+-----------------+
Questo esempio utilizza un CASE
cercato espressione per valutare i risultati da LatestRecordedPopulation
colonna di Application.Cities
tavolo.
Tipi di dati
In SQL Server, il tipo di dati dell'espressione di input e WHEN
le espressioni devono essere le stesse o devono essere una conversione implicita.
Ecco cosa succede se non lo sono:
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 1 THEN 'Apple'
WHEN 2 THEN 'Facebook'
WHEN 3 THEN 'Mastercard'
WHEN 4 THEN 'Visa'
ELSE 'Not in the portfolio'
END
Risultato:
Msg 245, Level 16, State 1, Line 3 Conversion failed when converting the varchar value 'V' to data type int.
Ordine di valutazione
Il CASE
di T-SQL espressione valuta le sue condizioni in sequenza e si ferma con la prima condizione la cui condizione è soddisfatta.
Per dimostrarlo, utilizziamo più WHEN
espressioni che condividono lo stesso valore:
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 'V' THEN 'Visa 1'
WHEN 'V' THEN 'Visa 2'
WHEN 'V' THEN 'Visa 3'
ELSE 'Not in the portfolio'
END
Risultato:
+-----------+ | Company | |-----------| | Visa 1 | +-----------+
In questo caso, si è fermato al primo WHEN
espressione.
Può verificarsi lo scenario occasionale in cui un'espressione viene valutata prima di un CASE
expression riceve i risultati dell'espressione come input. In tali scenari, potresti finire con un errore. Ciò potrebbe verificarsi se includi un'espressione aggregata come WHEN
espressione.
Per questo motivo, Microsoft consiglia che:
Dovresti dipendere solo dall'ordine di valutazione delle condizioni WHEN per le espressioni scalari (incluse le sottoquery non correlate che restituiscono scalari), non per le espressioni aggregate.
ELSE è facoltativo
Il ELSE
l'argomento è facoltativo. Pertanto, potremmo riscrivere il nostro esempio di "accessibilità economica" come segue:
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 THEN 'Expensive'
END
Risultato:
+-----------------+ | Affordability | |-----------------| | Expensive | +-----------------+
Tuttavia, tieni presente che potresti finire con NULL
se ometti ELSE
discussione.
L'esempio seguente restituisce NULL
:
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
END
Risultato:
+-----------------+ | Affordability | |-----------------| | NULL | +-----------------+
In questi casi, potremmo sempre aggiungere un ELSE
argomento, per ogni evenienza (scusate il gioco di parole!):
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
ELSE 'Unknown'
END
Risultato:
+-----------------+ | Affordability | |-----------------| | Unknown | +-----------------+
Certo, questo esempio è probabilmente un po' forzato. Dopotutto, non c'è bisogno di limitare "costoso". Se qualcosa costa meno di $ 1000, lo è anche se supera $ 1000.
Ma il punto è che puoi usare ELSE
per catturare tutto ciò che non è coperto da WHEN
espressione/i.
Espressioni CASE nidificate
Puoi annidare CASE
espressioni se richieste.
DECLARE @price int, @on_sale bit;
SET @price = 1500;
SET @on_sale = 1;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 THEN
CASE @on_sale
WHEN 0 THEN 'Expensive (but it''s not currently on sale)'
WHEN 1 THEN 'Expensive (and it''s already on sale!)'
END
END
Risultato:
+---------------------------------------+ | Affordability | |---------------------------------------| | Expensive (and it's already on sale!) | +---------------------------------------+
Tuttavia, è importante notare che per CASE
sono consentiti solo 10 livelli di nidificazione espressioni in SQL Server. Se provi a nidificare più di 10 livelli, riceverai un errore.
CASE in una clausola ORDER BY
Come accennato, il CASE
di T-SQL L'espressione può essere utilizzata in qualsiasi istruzione o clausola che consenta un'espressione valida. Pertanto, puoi usarlo in istruzioni come SELECT
, UPDATE
, DELETE
e SET
e in clausole come IN
, WHERE
, ORDER BY
, GROUP BY
e HAVING
.
Utilizzando un CASE
espressione in un ORDER BY
di un'istruzione La clausola può essere utile quando si desidera fare un'eccezione speciale per determinati valori quando si ordinano i risultati.
Supponiamo di eseguire la seguente query su una tabella contenente generi musicali.
SELECT Genre
FROM MusicGenres
ORDER BY Genre ASC;
Risultato:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Other | | Pop | | Rap | | Rock | +---------+
Qui ordiniamo i risultati in base al Genre
colonna, in ordine crescente.
Questo va bene tranne per una cosa. Il genere chiamato Altro . Non sarebbe bello se potessimo spostare Altro fino in fondo?
Possiamo raggiungere questo obiettivo con il CASE
espressione prendendo la query precedente e modificandola come segue.
SELECT Genre
FROM MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Risultato:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Pop | | Rap | | Rock | | Other | +---------+
CASE in una dichiarazione UPDATE
Ecco un esempio di utilizzo di un CASE
espressione in un UPDATE
dichiarazione.
Supponiamo di avere la seguente tabella:
+---------+-----------+-----------+----------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+----------| | 1 | Fetch | 1 | NULL | | 2 | Fluffy | 0 | NULL | | 3 | Wag | 0 | NULL | | 1001 | Brian | 1 | NULL | | 1002 | Rambo | 0 | NULL | | 1003 | BamBam | 1 | NULL | +---------+-----------+-----------+----------+
Di recente abbiamo aggiunto la Dinner
colonna, ed è ancora NULL
, in attesa di inserimento dei valori.
Ma i valori da inserire dipenderanno dal valore del GoodDog
colonna.
Potremmo usare un CASE
espressione in un tale scenario.
UPDATE Dogs
SET Dinner =
CASE GoodDog
WHEN 1 THEN 'Sunday Roast'
ELSE 'Airline food'
END
SELECT * FROM Dogs;
Risultato:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1 | Fetch | 1 | Sunday Roast | | 2 | Fluffy | 0 | Airline food | | 3 | Wag | 0 | Airline food | | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
CASO in una dichiarazione INSERT
Possiamo prendere la tabella dall'esempio sopra e inserire un nuovo valore.
E possiamo di nuovo sfruttare il CASE
espressione per inserire il valore appropriato nella Dinner
colonna.
DECLARE @DogName nvarchar(60), @GoodDog bit;
SET @DogName = 'Lazy';
SET @GoodDog = 0;
INSERT INTO Dogs ( DogName, GoodDog, Dinner )
VALUES (
@DogName,
@GoodDog,
CASE @GoodDog
WHEN 1 THEN 'Sunday Roast'
ELSE 'Airline food'
END
);
SELECT * FROM Dogs;
Risultato:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1 | Fetch | 1 | Sunday Roast | | 2 | Fluffy | 0 | Airline food | | 3 | Wag | 0 | Airline food | | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
Questa volta il CASE
espressione stava valutando il valore di una variabile che avevamo appena impostato, quindi inserendo il valore appropriato nella Dinner
colonna.
È un'istruzione CASE o un'espressione CASE?
In SQL, molte cose vengono chiamate "dichiarazioni" quando in realtà sono qualcos'altro. Questo sembra essere vero anche per il T-SQL "CASE
dichiarazione”.
Sebbene sia spesso indicato come CASE
dichiarazione, è più accurato chiamarla CASE
espressione . Questo è anche il modo in cui lo fa riferimento la documentazione Microsoft.
In SQL Server, anziché essere un'istruzione stessa, CASE
può essere utilizzato in qualsiasi istruzione o clausola che consenta un'espressione valida. Un'espressione è una combinazione di simboli e operatori che vengono valutati per ottenere un unico valore di dati.
Tuttavia, alcuni DBMS distinguono tra CASE
istruzione e il CASE
espressione e hanno una sintassi leggermente diversa per ciascuno. MySQL distingue tra CASE
dichiarazione e il CASE
operatore, che è essenzialmente lo stesso di CASE
espressione.