Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Espressione CASE di SQL Server

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.