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

SQL CASE-erklæring

I SQL er CASE sætning evaluerer en liste over betingelser og returnerer et af flere mulige resultatudtryk.

På nogle måder er SQL CASE sætningen ligner IF...ELSE erklæring ved, at det giver os mulighed for at tjekke for en given tilstand og returnere et andet resultat afhængigt af resultatet.

Er det en CASE Erklæring eller CASE Udtryk?

I SQL omtales ting nogle gange som en "erklæring", når de faktisk er noget andet. SQL'en "CASE statement” er et eksempel (undskyld ordspillet!).

CASE sætning omtales i SQL-standarden (ISO/IEC 9075) som CASE udtryk . Dens formål er at "specificere en betinget værdi".

Nogle DBMS'er skelner dog mellem CASE sætning og CASE udtryk og har en lidt forskellig syntaks for hver. For eksempel leverer både MySQL og MariaDB CASE sætning og CASE operator som to forskellige funktioner, hver med lidt forskellig syntaks.

CASE Formater

I SQL er der to formater af CASE udtryk:

  • Simpel CASE udtryk
  • Søgte i CASE udtryk

Nedenfor er eksempler på hver.

Den simple CASE Udtryk

Den simple CASE udtryk sammenligner et udtryk med et sæt simple udtryk for at bestemme resultatet.

Eksempel:

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;

Resultat:

Grass

Dette eksempel blev udført i MySQL, men den faktiske CASE udtryk bør fungere på tværs af de fleste større RDBMS'er.

I dette eksempel er min CASE udtryk er en del af en SELECT udmelding. Den tjekker for tre forhold og har en ELSE at tage højde for alt, der ikke er dækket af de tre betingelser.

I dette tilfælde dyret Cow matcher den tredje WHEN udtryk og udtrykket leveret af dets THEN er returneret.

For at være klar, den faktiske CASE udtryk er denne del:

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

Hvilken CASE er at kontrollere værdien af ​​hver WHEN udtryk mod inputudtrykket. I dette eksempel er @animal variabel er input-udtrykket. Derfor tjekker den værdien af ​​hver WHEN udtryk mod @animal variabel.

Når/hvis den finder et match, returnerer den udtrykket leveret af den tilsvarende THEN .

Mit eksempel bruger tre WHEN udtryk, men jeg kunne have brugt mere, og jeg kunne have brugt mindre, afhængig af kravene.

Den søgte CASE Udtryk

Den søgte CASE udtryk evaluerer et sæt boolske udtryk for at bestemme resultatet.

Her er et eksempel på en søgt CASE udtryk.

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;

Resultat:

Well done!

Den søgte CASE udtryk har ikke et input-udtryk som den simple CASE udtryk.

Du husker det i vores simple CASE udtryk, det startede med CASE @animal , og derfor vidste vi, at WHEN alle udtryk blev evalueret mod værdien af ​​@animal .

Med den søgte CASE udtryk, giver vi ikke et input-udtryk i starten på den måde. I stedet skal hver WHEN udtryk inkluderer et boolesk udtryk, som der skal evalueres i forhold til.

Et databaseeksempel

Her er et eksempel, der viser, hvordan CASE udtryk kan bruges i en databaseforespørgsel.

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;

Resultat:

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

Dette eksempel bruger en søgt CASE udtryk for at evaluere resultaterne fra Population kolonne i City bord.

ELSE er valgfrit

ELSE argument er valgfrit. Hvis vi udelader ELSE , og ingen af ​​betingelserne udløses, er resultatet NULL .

Her er, hvad der sker, når vi udelader ELSE klausul fra det foregående eksempel:

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;

Resultat:

+---------------+------------+-----------+
| 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 i en UPDATE Erklæring

Lad os tilføje en kolonne til City tabel fra det foregående eksempel:

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

SELECT * FROM City
LIMIT 10;

Sådan ser det ud nu:

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

Vi har ikke indsat nogen data i den nye Size kolonne, så den returnerer NULL i hver række.

Vi kan nu bruge en CASE udtryk for at opdatere Size kolonne med en værdi, der afhænger af værdien i Population kolonne:

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

Lad os nu vælge data fra tabellen:

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

Resultat:

+------+---------------+-------------+---------------+------------+------------+
| 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 i en INSERT Erklæring

Antag, at vi har følgende tabel i en SQL Server-database:

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

Lad os indsætte en ny række i den tabel. Men lad os bruge CASE udtryk for at indsætte den passende værdi i Dinner kolonne, afhængigt af værdien i GoodDog kolonne:

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

Her er CASE expression evaluerede værdien af ​​en variabel, vi lige havde indstillet, og indsatte derefter den passende værdi i Dinner kolonne.

Lad os nu tjekke tabellen igen:

SELECT * FROM Dogs;

Resultat:

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

Vi kan se, at den passende værdi er i Dinner kolonne.

CASE i en ORDER BY Klausul

CASE udtryk kan bruges i enhver sætning eller klausul, der tillader et gyldigt udtryk. Derfor kan du bruge det i sætninger såsom SELECT , UPDATE , DELETE og SET , og i klausuler såsom IN , WHERE , ORDER BY , GROUP BY og HAVING .

Brug af en CASE udtryk i en sætnings ORDER BY klausul kan være praktisk, når du vil gøre en særlig undtagelse for bestemte værdier, når du bestiller dine resultater.

Antag, at vi kører følgende forespørgsel mod en tabel, der indeholder musikgenrer.

SELECT Genre 
FROM Genres
ORDER BY Genre ASC;

Resultat:

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

Her sorterer vi resultaterne efter Genre kolonne i stigende rækkefølge.

Det er fint bortset fra én ting. Genren kaldet Other . Ville det ikke være rart, hvis vi kunne flytte Other til bunden?

Vi kan opnå dette med CASE udtryk ved at tage ovenstående forespørgsel og ændre den som følger.

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

Resultat:

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

COALESCE() og NULLIF() Funktioner

Afhængigt af scenariet kan vi bruge funktioner såsom COALESCE() og NULLIF() som en genvej i stedet for at bruge CASE udtryk.

Disse to funktioner er SQL-standard, og de fungerer som følger:

NULLIF (V1, V2)

Er svarende til:

CASE WHEN V1=V2 THEN NULL ELSE V1 END

Og:

COALESCE (V1, V2)

Er svarende til:

CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END

Også:

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

Er svarende til:

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

  1. Forespørgsel for at finde fuld tabelscanninger i Oracle

  2. Design af en Microsoft T-SQL Trigger

  3. Nulstil root-adgangskoden til MySQL på Windows

  4. ERD-notationer i datamodellering