sql >> Database >  >> RDS >> Mysql

SQL CASE-instructie

In SQL is de CASE statement evalueert een lijst met voorwaarden en retourneert een van meerdere mogelijke resultaatuitdrukkingen.

In sommige opzichten is de SQL CASE statement lijkt een beetje op de IF...ELSE verklaring in dat het ons in staat stelt om te controleren op een bepaalde voorwaarde en een ander resultaat te retourneren, afhankelijk van de uitkomst.

Is het een CASE Verklaring of CASE Uitdrukking?

In SQL worden dingen soms een "statement" genoemd, terwijl ze in feite iets anders zijn. De SQL “CASE statement” is een goed voorbeeld (sorry voor de woordspeling!).

De CASE statement wordt in de SQL-standaard (ISO/IEC 9075) aangeduid als de CASE uitdrukking . Het doel is om "een voorwaardelijke waarde op te geven".

Sommige DBMS'en maken echter onderscheid tussen de CASE statement en de CASE expressie, en hebben voor elk een iets andere syntaxis. Zowel MySQL als MariaDB bieden bijvoorbeeld de CASE statement en de CASE operator als twee verschillende functies, elk met een iets andere syntaxis.

CASE Formaten

In SQL zijn er twee formaten van CASE uitdrukking:

  • Eenvoudige CASE uitdrukking
  • Gezocht CASE uitdrukking

Hieronder staan ​​voorbeelden van elk.

De eenvoudige CASE Uitdrukking

De eenvoudige CASE uitdrukking vergelijkt een uitdrukking met een reeks eenvoudige uitdrukkingen om het resultaat te bepalen.

Voorbeeld:

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;

Resultaat:

Grass

Dit voorbeeld is gemaakt in MySQL, maar de eigenlijke CASE expressie zou in de meeste grote RDBMS'en moeten werken.

In dit voorbeeld is mijn CASE expressie maakt deel uit van een SELECT uitspraak. Het controleert op drie voorwaarden en heeft een ELSE om te voorzien in alles wat niet onder de drie voorwaarden valt.

In dit geval het dier Cow komt overeen met de derde WHEN expressie, en de expressie geleverd door zijn THEN wordt geretourneerd.

Voor alle duidelijkheid:de eigenlijke CASE uitdrukking is dit deel:

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

Wat CASE doet is de waarde van elke WHEN . controleren expressie tegen de invoerexpressie. In dit voorbeeld is de @animal variabele is de invoerexpressie. Daarom controleert het de waarde van elke WHEN uitdrukking tegen de @animal variabel.

Wanneer/als het een overeenkomst vindt, retourneert het de uitdrukking die wordt geleverd door de corresponderende THEN .

Mijn voorbeeld gebruikt drie WHEN uitdrukkingen, maar ik had meer en minder kunnen gebruiken, afhankelijk van de vereisten.

De gezochte CASE Uitdrukking

De gezochte CASE expression evalueert een set Booleaanse expressies om het resultaat te bepalen.

Hier is een voorbeeld van een gezochte CASE uitdrukking.

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;

Resultaat:

Well done!

De gezochte CASE expressie heeft geen invoerexpressie zoals de eenvoudige CASE uitdrukking.

U herinnert zich dat in onze eenvoudige CASE uitdrukking, het begon met CASE @animal , en daarom wisten we dat de WHEN expressies evalueerden allemaal tegen de waarde van @animal .

Met de gezochte CASE expressie, bieden we aan het begin geen invoerexpressie op die manier. In plaats daarvan wordt elke WHEN expressie bevat een Booleaanse expressie waarvoor geëvalueerd moet worden.

Een databasevoorbeeld

Hier is een voorbeeld dat laat zien hoe de CASE expressie kan worden gebruikt binnen een databasequery.

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;

Resultaat:

+---------------+------------+------------+
| 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 |
+---------------+------------+------------+

Dit voorbeeld gebruikt een gezochte CASE expressie om de resultaten van de Population . te evalueren kolom van de City tafel.

ELSE is optioneel

De ELSE argument is optioneel. Als we de ELSE . weglaten , en geen van de voorwaarden wordt geactiveerd, is het resultaat NULL .

Dit is wat er gebeurt als we de ELSE weglaten clausule uit het vorige voorbeeld:

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;

Resultaat:

+---------------+------------+-----------+
| 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 een UPDATE Verklaring

Laten we een kolom toevoegen aan de City tabel uit het vorige voorbeeld:

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

SELECT * FROM City
LIMIT 10;

Zo ziet het er nu uit:

+----+----------------+-------------+---------------+------------+------+
| 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 |
+----+----------------+-------------+---------------+------------+------+

We hebben geen gegevens ingevoegd in de nieuwe Size kolom, dus het retourneert NULL in elke rij.

We kunnen nu een CASE . gebruiken expressie om de Size . bij te werken kolom met een waarde die afhangt van de waarde in de Population kolom:

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

Laten we nu gegevens uit de tabel selecteren:

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

Resultaat:

+------+---------------+-------------+---------------+------------+------------+
| 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 een INSERT Verklaring

Stel dat we de volgende tabel in een SQL Server-database hebben:

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

Laten we een nieuwe rij in die tabel invoegen. Maar laten we de CASE . gebruiken expressie om de juiste waarde in te voegen in het Dinner kolom, afhankelijk van de waarde in de GoodDog kolom:

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
    );

Hier, de CASE expression evalueerde de waarde van een variabele die we zojuist hadden ingesteld en voegde vervolgens de juiste waarde toe aan het Dinner kolom.

Laten we nu de tabel opnieuw bekijken:

SELECT * FROM Dogs;

Resultaat:

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

We kunnen zien dat de juiste waarde in het Dinner . staat kolom.

CASE in een ORDER BY Clausule

De CASE expressie kan worden gebruikt in elke instructie of clausule die een geldige expressie toestaat. Daarom kunt u het gebruiken in instructies zoals SELECT , UPDATE , DELETE en SET , en in clausules zoals IN , WHERE , ORDER BY , GROUP BY , en HAVING .

Een CASE gebruiken uitdrukking in de ORDER BY . van een instructie clausule kan handig zijn wanneer u een speciale uitzondering wilt maken voor bepaalde waarden bij het bestellen van uw resultaten.

Stel dat we de volgende query uitvoeren op een tabel met muziekgenres.

SELECT Genre 
FROM Genres
ORDER BY Genre ASC;

Resultaat:

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

Hier rangschikken we de resultaten op Genre kolom, in oplopende volgorde.

Dit is prima, op één ding na. Het genre genaamd Other . Zou het niet mooi zijn als we Other . konden verplaatsen naar beneden?

We kunnen dit bereiken met de CASE expressie door de bovenstaande query te nemen en deze als volgt aan te passen.

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

Resultaat:

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

De COALESCE() en NULLIF() Functies

Afhankelijk van het scenario kunnen we functies gebruiken zoals COALESCE() en NULLIF() als een snelkoppeling, in plaats van de CASE uitdrukking.

Deze twee functies zijn standaard SQL en werken als volgt:

NULLIF (V1, V2)

Is gelijk aan:

CASE WHEN V1=V2 THEN NULL ELSE V1 END

En:

COALESCE (V1, V2)

Is gelijk aan:

CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END

Ook:

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

Is gelijk aan:

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

  1. Inleiding tot gegevenskoppelingen en -relaties

  2. Waarde Fout bij het importeren van gegevens in de postgres-tabel met psycopg2

  3. OPTIE (HERCOMPIEREN) is altijd sneller; Waarom?

  4. Query met meerdere waarden in een kolom