sql >> Databáze >  >> RDS >> Mysql

Příkaz SQL CASE

V SQL, CASE příkaz vyhodnotí seznam podmínek a vrátí jeden z více možných výsledných výrazů.

V některých ohledech CASE SQL příkaz je podobný příkazu IF...ELSE prohlášení v tom, že nám umožňuje zkontrolovat danou podmínku a vrátit jiný výsledek v závislosti na výsledku.

Je to CASE Prohlášení nebo CASE Výraz?

V SQL se někdy věci označují jako „příkaz“, i když ve skutečnosti jde o něco jiného. SQL „CASE statement“ je názorným příkladem (omlouvám se za slovní hříčku!).

CASE příkaz je ve standardu SQL (ISO/IEC 9075) označován jako CASE výraz . Jeho účelem je „specifikovat podmíněnou hodnotu“.

Některé DBMS však rozlišují mezi CASE a CASE výraz a mají pro každý trochu jinou syntaxi. Například MySQL i MariaDB poskytují CASE a CASE operátor jako dvě odlišné funkce, každá s mírně odlišnou syntaxí.

CASE Formáty

V SQL existují dva formáty CASE výraz:

  • Jednoduchý CASE výraz
  • Hledali jste CASE výraz

Níže jsou uvedeny příklady každého z nich.

Jednoduchý CASE Výraz

Jednoduchý CASE výraz porovnává výraz se sadou jednoduchých výrazů a určuje výsledek.

Příklad:

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;

Výsledek:

Grass

Tento příklad byl proveden v MySQL, ale skutečný CASE výraz by měl fungovat ve většině hlavních RDBMS.

V tomto příkladu můj CASE výraz je součástí SELECT prohlášení. Kontroluje tři podmínky a má ELSE uspokojit vše, co není zahrnuto ve třech podmínkách.

V tomto případě zvíře Cow odpovídá třetímu WHEN výraz a výraz poskytnutý jeho THEN je vráceno.

Aby bylo jasno, skutečný CASE výraz je tato část:

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

Jaký CASE zkontroluje hodnotu každého WHEN výraz proti vstupnímu výrazu. V tomto příkladu @animal proměnná je vstupní výraz. Proto kontroluje hodnotu každého WHEN výraz proti @animal proměnná.

Když/pokud najde shodu, vrátí výraz poskytnutý odpovídajícím THEN .

Můj příklad používá tři WHEN výrazů, ale mohl jsem použít více a mohl jsem použít méně, v závislosti na požadavcích.

Hledaný CASE Výraz

Hledaný CASE expression vyhodnotí sadu booleovských výrazů k určení výsledku.

Zde je příklad hledaného CASE výraz.

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;

Výsledek:

Well done!

Hledaný CASE výraz nemá vstupní výraz jako jednoduchý CASE výraz.

Připomenete si to v našem jednoduchém CASE výraz, začalo to CASE @animal , a proto jsme věděli, že WHEN všechny výrazy byly vyhodnoceny oproti hodnotě @animal .

S hledaným CASE výraz, neposkytujeme vstupní výraz na začátku, jako je tento. Místo toho každý WHEN výraz obsahuje booleovský výraz, pro který má být vyhodnocen.

Příklad databáze

Zde je příklad, který ukazuje, jak CASE výraz lze použít v databázovém dotazu.

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;

Výsledek:

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

Tento příklad používá hledaný CASE výraz pro vyhodnocení výsledků z Population ve sloupci City stůl.

ELSE je volitelný

ELSE argument je volitelný. Pokud vynecháme ELSE a není spuštěna žádná z podmínek, výsledkem je NULL .

Co se stane, když vynecháme ELSE klauzule z předchozího příkladu:

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;

Výsledek:

+---------------+------------+-----------+
| 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 v UPDATE Prohlášení

Pojďme přidat sloupec do City tabulka z předchozího příkladu:

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

SELECT * FROM City
LIMIT 10;

Tady je to, jak to teď vypadá:

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

Do nové Size jsme nevložili žádná data sloupec, takže vrátí NULL v každém řádku.

Nyní můžeme použít CASE výraz pro aktualizaci Size sloupec s hodnotou, která závisí na hodnotě v Population sloupec:

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

Nyní vybereme data z tabulky:

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

Výsledek:

+------+---------------+-------------+---------------+------------+------------+
| 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 v INSERT Prohlášení

Předpokládejme, že máme v databázi SQL Serveru následující tabulku:

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

Vložíme do této tabulky nový řádek. Ale použijme CASE výraz pro vložení příslušné hodnoty do Dinner v závislosti na hodnotě v GoodDog sloupec:

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

Zde je CASE výraz vyhodnotil hodnotu proměnné, kterou jsme právě nastavili, a poté vložil příslušnou hodnotu do Dinner sloupec.

Nyní znovu zkontrolujeme tabulku:

SELECT * FROM Dogs;

Výsledek:

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

Vidíme, že příslušná hodnota je v Dinner sloupec.

CASE v ORDER BY Ustanovení

CASE výraz lze použít v jakémkoli příkazu nebo klauzuli, která umožňuje platný výraz. Proto jej můžete použít v příkazech jako SELECT , UPDATE , DELETE a SET a v klauzulích jako IN , WHERE , ORDER BY , GROUP BY a HAVING .

Pomocí CASE výraz v příkazu ORDER BY klauzule může být užitečná, když chcete při řazení výsledků udělat zvláštní výjimku pro určité hodnoty.

Předpokládejme, že spustíme následující dotaz proti tabulce obsahující hudební žánry.

SELECT Genre 
FROM Genres
ORDER BY Genre ASC;

Výsledek:

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

Zde seřadíme výsledky podle Genre sloupec, ve vzestupném pořadí.

To je fajn, až na jednu věc. Žánr s názvem Other . Nebylo by hezké, kdybychom mohli přesunout Other na dno?

Toho můžeme dosáhnout pomocí CASE výraz tím, že vezmete výše uvedený dotaz a upravíte jej následovně.

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

Výsledek:

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

COALESCE() a NULLIF() Funkce

V závislosti na scénáři můžeme použít funkce jako COALESCE() a NULLIF() jako zkratku namísto použití CASE výraz.

Tyto dvě funkce jsou standardem SQL a fungují následovně:

NULLIF (V1, V2)

Je ekvivalentní:

CASE WHEN V1=V2 THEN NULL ELSE V1 END

A:

COALESCE (V1, V2)

Je ekvivalentní:

CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END

Také:

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

Je ekvivalentní:

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

  1. Oznámení ClusterControl 1.7.3:Vylepšená podpora PostgreSQL a nové možnosti nasazení cloudu

  2. Neuspořádané výsledky v SQL

  3. Srovnávání manuálního nasazení databáze vs. automatizovaná nasazení

  4. Jak zjistit, zda je MySQLnd aktivním ovladačem?