Mysql
 sql >> Database >  >> RDS >> Mysql

Istruzione SQL CASE

In SQL, il CASE istruzione valuta un elenco di condizioni e restituisce una delle più possibili espressioni di risultato.

In un certo senso, l'SQL CASE è un po' simile all'istruzione IF...ELSE affermazione in quanto ci consente di verificare una data condizione e restituire un risultato diverso a seconda del risultato.

È un CASE Dichiarazione o CASE Espressione?

In SQL, a volte le cose vengono chiamate "dichiarazioni" quando in realtà sono qualcos'altro. L'SQL "CASE dichiarazione” è un esempio calzante (scusate il gioco di parole!).

Il CASE è indicato nello standard SQL (ISO/IEC 9075) come CASE espressione . Il suo scopo è “specificare un valore condizionale”.

Tuttavia, alcuni DBMS distinguono tra CASE dichiarazione e il CASE espressione e hanno una sintassi leggermente diversa per ciascuno. Ad esempio, sia MySQL che MariaDB forniscono il CASE dichiarazione e il CASE operatore come due caratteristiche distinte, ciascuna con una sintassi leggermente diversa.

CASE Formati

In SQL, ci sono due formati di CASE espressione:

  • Semplice CASE espressione
  • Cercato CASE espressione

Di seguito sono riportati esempi di ciascuno.

Il semplice CASE Espressione

Il semplice CASE expression confronta un'espressione con un insieme di espressioni semplici per determinare il risultato.

Esempio:

DECLARE @animal VARCHAR(40);
SET @animal = 'Cow';

SELECT  
    CASE @animal  
        WHEN 'Bird' THEN 'Seed'
        WHEN 'Dog' THEN 'Beef'
        WHEN 'Cow' THEN 'Grass'
        ELSE 'Leftovers'  
    END;

Risultato:

Grass

Questo esempio è stato eseguito in MySQL, ma l'attuale CASE l'espressione dovrebbe funzionare sulla maggior parte dei principali RDBMS.

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, l'animale Cow corrisponde al terzo WHEN espressione e l'espressione fornita dal relativo THEN viene restituito.

Per essere chiari, il vero CASE l'espressione è questa parte:

    CASE @animal  
        WHEN 'Bird' THEN 'Seed'
        WHEN 'Dog' THEN 'Beef'
        WHEN 'Cow' THEN 'Grass'
        ELSE 'Leftovers'  
    END

Quale CASE non resta che controllare il valore di ogni WHEN espressione contro l'espressione di input. In questo esempio, il @animal variabile è l'espressione di input. Pertanto, sta verificando il valore di ogni WHEN espressione contro @animal variabile.

Quando/se trova una corrispondenza, restituisce l'espressione fornita dal corrispondente THEN .

Il mio esempio usa tre WHEN espressioni, ma avrei potuto usarne di più e avrei potuto usarne di meno, a seconda delle esigenze.

Il CASE cercato Espressione

Il CASE cercato expression valuta un insieme di espressioni booleane per determinare il risultato.

Ecco un esempio di un CASE cercato espressione.

DECLARE @score int;
SET @score = 7;

SELECT
    CASE   
        WHEN @score > 8 THEN 'Congratulations!'
        WHEN @score > 5 AND @score < 8 THEN 'Well done!'
        ELSE 'Try harder next time'  
    END;

Risultato:

Well done!

Il CASE cercato espressione non ha un'espressione di input come il semplice CASE espressione.

Lo ricorderai nel nostro semplice CASE espressione, è iniziato con CASE @animal , e quindi sapevamo che il WHEN le espressioni stavano tutte valutando rispetto al valore di @animal .

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 World;
SELECT
    Name,
    Population,
      CASE 
         WHEN Population > 2000000 THEN 'Huge City'  
         WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City' 
         ELSE 'Small City'
      END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;

Risultato:

+---------------+------------+------------+
| Name          | Population | Size       |
+---------------+------------+------------+
| New York      |    8008278 | Huge City  |
| Los Angeles   |    3694820 | Huge City  |
| Chicago       |    2896016 | Huge City  |
| Houston       |    1953631 | Big City   |
| Philadelphia  |    1517550 | Big City   |
| Phoenix       |    1321045 | Big City   |
| San Diego     |    1223400 | Big City   |
| Dallas        |    1188580 | Big City   |
| San Antonio   |    1144646 | Big City   |
| Detroit       |     951270 | Small City |
| San Jose      |     894943 | Small City |
| Indianapolis  |     791926 | Small City |
| San Francisco |     776733 | Small City |
| Jacksonville  |     735167 | Small City |
| Columbus      |     711470 | Small City |
| Austin        |     656562 | Small City |
| Baltimore     |     651154 | Small City |
| Memphis       |     650100 | Small City |
| Milwaukee     |     596974 | Small City |
| Boston        |     589141 | Small City |
+---------------+------------+------------+

Questo esempio utilizza un CASE cercato espressione per valutare i risultati dalla Population colonna della City tavolo.

ELSE è facoltativo

Il ELSE l'argomento è facoltativo. Se omettiamo ELSE e nessuna delle condizioni viene attivata, il risultato è NULL .

Ecco cosa succede quando omettiamo ELSE clausola dell'esempio precedente:

USE World;
SELECT
    Name,
    Population,
      CASE 
         WHEN Population > 2000000 THEN 'Huge City'  
         WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
      END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;

Risultato:

+---------------+------------+-----------+
| Name          | Population | Size      |
+---------------+------------+-----------+
| New York      |    8008278 | Huge City |
| Los Angeles   |    3694820 | Huge City |
| Chicago       |    2896016 | Huge City |
| Houston       |    1953631 | Big City  |
| Philadelphia  |    1517550 | Big City  |
| Phoenix       |    1321045 | Big City  |
| San Diego     |    1223400 | Big City  |
| Dallas        |    1188580 | Big City  |
| San Antonio   |    1144646 | Big City  |
| Detroit       |     951270 | NULL      |
| San Jose      |     894943 | NULL      |
| Indianapolis  |     791926 | NULL      |
| San Francisco |     776733 | NULL      |
| Jacksonville  |     735167 | NULL      |
| Columbus      |     711470 | NULL      |
| Austin        |     656562 | NULL      |
| Baltimore     |     651154 | NULL      |
| Memphis       |     650100 | NULL      |
| Milwaukee     |     596974 | NULL      |
| Boston        |     589141 | NULL      |
+---------------+------------+-----------+

CASE in un UPDATE Dichiarazione

Aggiungiamo una colonna a City tabella dell'esempio precedente:

ALTER TABLE City
ADD COLUMN Size VARCHAR(30) AFTER Population;

SELECT * FROM City
LIMIT 10;

Ecco come appare ora:

+----+----------------+-------------+---------------+------------+------+
| ID | Name           | CountryCode | District      | Population | Size |
+----+----------------+-------------+---------------+------------+------+
|  1 | Kabul          | AFG         | Kabol         |    1780000 | NULL |
|  2 | Qandahar       | AFG         | Qandahar      |     237500 | NULL |
|  3 | Herat          | AFG         | Herat         |     186800 | NULL |
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 | NULL |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 | NULL |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 | NULL |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 | NULL |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 | NULL |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 | NULL |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 | NULL |
+----+----------------+-------------+---------------+------------+------+

Non abbiamo inserito alcun dato nella nuova Size colonna, quindi restituisce NULL in ogni riga.

Ora possiamo usare un CASE espressione per aggiornare il Size colonna con un valore che dipende dal valore nella Population colonna:

UPDATE City 
SET Size = 
    CASE 
        WHEN Population > 2000000 THEN 'Huge City'  
        WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
        ELSE 'Small City'
    END;

Ora selezioniamo i dati dalla tabella:

SELECT * FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;

Risultato:

+------+---------------+-------------+---------------+------------+------------+
| ID   | Name          | CountryCode | District      | Population | Size       |
+------+---------------+-------------+---------------+------------+------------+
| 3793 | New York      | USA         | New York      |    8008278 | Huge City  |
| 3794 | Los Angeles   | USA         | California    |    3694820 | Huge City  |
| 3795 | Chicago       | USA         | Illinois      |    2896016 | Huge City  |
| 3796 | Houston       | USA         | Texas         |    1953631 | Big City   |
| 3797 | Philadelphia  | USA         | Pennsylvania  |    1517550 | Big City   |
| 3798 | Phoenix       | USA         | Arizona       |    1321045 | Big City   |
| 3799 | San Diego     | USA         | California    |    1223400 | Big City   |
| 3800 | Dallas        | USA         | Texas         |    1188580 | Big City   |
| 3801 | San Antonio   | USA         | Texas         |    1144646 | Big City   |
| 3802 | Detroit       | USA         | Michigan      |     951270 | Small City |
| 3803 | San Jose      | USA         | California    |     894943 | Small City |
| 3804 | Indianapolis  | USA         | Indiana       |     791926 | Small City |
| 3805 | San Francisco | USA         | California    |     776733 | Small City |
| 3806 | Jacksonville  | USA         | Florida       |     735167 | Small City |
| 3807 | Columbus      | USA         | Ohio          |     711470 | Small City |
| 3808 | Austin        | USA         | Texas         |     656562 | Small City |
| 3809 | Baltimore     | USA         | Maryland      |     651154 | Small City |
| 3810 | Memphis       | USA         | Tennessee     |     650100 | Small City |
| 3811 | Milwaukee     | USA         | Wisconsin     |     596974 | Small City |
| 3812 | Boston        | USA         | Massachusetts |     589141 | Small City |
+------+---------------+-------------+---------------+------------+------------+

CASE in un INSERT Dichiarazione

Supponiamo di avere la seguente tabella in un database di SQL Server:

+---------+-----------+-----------+--------------+
| DogId   | DogName   | GoodDog   | Dinner       |
|---------+-----------+-----------+--------------|
| 1001    | Brian     | 1         | Sunday Roast |
| 1002    | Rambo     | 0         | Airline food |
| 1003    | BamBam    | 1         | Sunday Roast |
+---------+-----------+-----------+--------------+

Inseriamo una nuova riga in quella tabella. Ma usiamo il CASE espressione per inserire il valore appropriato nella Dinner colonna, a seconda del valore in GoodDog 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
    );

Qui, il CASE expression ha valutato il valore di una variabile che avevamo appena impostato, quindi ha inserito il valore appropriato nella Dinner colonna.

Ora controlliamo di nuovo la tabella:

SELECT * FROM Dogs;

Risultato:

+---------+-----------+-----------+--------------+
| DogId   | DogName   | GoodDog   | Dinner       |
|---------+-----------+-----------+--------------|
| 1001    | Brian     | 1         | Sunday Roast |
| 1002    | Rambo     | 0         | Airline food |
| 1003    | BamBam    | 1         | Sunday Roast |
| 1004    | Lazy      | 0         | Airline food |
+---------+-----------+-----------+--------------+

Possiamo vedere che il valore appropriato è in Dinner colonna.

CASE in un ORDER BY Clausola

Il CASE 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 Genres
ORDER BY Genre ASC;

Risultato:

+---------+
| Genre   |
+---------+
| Blues   |
| Country |
| Hip Hop |
| Jazz    |
| Other   |
| Pop     |
| Punk    |
| Rap     |
| Rock    |
+---------+

Qui ordiniamo i risultati in base al Genre colonna, in ordine crescente.

Questo va bene tranne per una cosa. Il genere chiamato Other . Non sarebbe bello se potessimo spostare Other fino in fondo?

Possiamo raggiungere questo obiettivo con il CASE espressione prendendo la query precedente e modificandola come segue.

SELECT Genre
FROM Genres
ORDER BY 
    CASE Genre
        WHEN 'Other' THEN 1
        ELSE 0
    END
    ASC, Genre ASC;

Risultato:

+---------+
| Genre   |
+---------+
| Blues   |
| Country |
| Hip Hop |
| Jazz    |
| Pop     |
| Punk    |
| Rap     |
| Rock    |
| Other   |
+---------+

Il COALESCE() e NULLIF() Funzioni

A seconda dello scenario possiamo utilizzare funzioni come COALESCE() e NULLIF() come scorciatoia, invece di usare il CASE espressione.

Queste due funzioni sono standard SQL e funzionano come segue:

NULLIF (V1, V2)

Equivale a:

CASE WHEN V1=V2 THEN NULL ELSE V1 END

E:

COALESCE (V1, V2)

Equivale a:

CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END

Inoltre:

COALESCE (V1, V2, ..., Vn)

Equivale a:

CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2, ..., Vn) END