Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Instrukcja SQL CASE

W SQL CASE instrukcja ocenia listę warunków i zwraca jedno z wielu możliwych wyrażeń wynikowych.

W pewnym sensie SQL CASE Instrukcja jest podobna do IF...ELSE stwierdzenie, że pozwala nam sprawdzić dany warunek i zwrócić inny wynik w zależności od wyniku.

Czy to CASE? Oświadczenie lub CASE Wyrażenie?

W SQL czasami rzeczy są określane jako „oświadczenie”, podczas gdy w rzeczywistości są czymś innym. SQL „CASE oświadczenie” jest tego przykładem (przepraszam za kalambur!).

CASE instrukcja jest określana w standardzie SQL (ISO/IEC 9075) jako CASE wyrażenie . Jego celem jest „określenie wartości warunkowej”.

Jednak niektóre DBMS rozróżniają CASE oświadczenie i CASE wyrażenie i mają nieco inną składnię dla każdego. Na przykład zarówno MySQL, jak i MariaDB zapewniają CASE oświadczenie i CASE operator jako dwie różne cechy, każda z nieco inną składnią.

CASE Formaty

W SQL istnieją dwa formaty CASE wyrażenie:

  • Prosty CASE wyrażenie
  • Przeszukano CASE wyrażenie

Poniżej znajdują się przykłady każdego z nich.

Prosty CASE Wyrażenie

Prosty CASE wyrażenie porównuje wyrażenie z zestawem prostych wyrażeń w celu określenia wyniku.

Przykład:

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;

Wynik:

Grass

Ten przykład został wykonany w MySQL, ale rzeczywisty CASE wyrażenie powinno działać w większości głównych systemów RDBMS.

W tym przykładzie mój CASE wyrażenie jest częścią SELECT oświadczenie. Sprawdza trzy warunki i ma ELSE aby zaspokoić wszystko, co nie jest objęte tymi trzema warunkami.

W tym przypadku zwierzę Cow pasuje do trzeciego WHEN wyrażenie i wyrażenie dostarczone przez jego THEN jest zwracany.

Żeby było jasne, rzeczywisty CASE wyrażenie to ta część:

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

Jaki CASE sprawdza wartość każdego WHEN wyrażenie w stosunku do wyrażenia wejściowego. W tym przykładzie @animal zmienna jest wyrażeniem wejściowym. Dlatego sprawdza wartość każdego WHEN wyrażenie przeciwko @animal zmienna.

Kiedy/jeśli znajdzie dopasowanie, zwraca wyrażenie dostarczone przez odpowiedni THEN .

Mój przykład używa trzech WHEN wyrażeń, ale mogłem użyć więcej i mogłem użyć mniej, w zależności od wymagań.

Przeszukiwany CASE Wyrażenie

Wyszukiwany CASE wyrażenie oblicza zestaw wyrażeń logicznych w celu określenia wyniku.

Oto przykład przeszukiwanego CASE wyrażenie.

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;

Wynik:

Well done!

Wyszukiwany CASE wyrażenie nie ma wyrażenia wejściowego, takiego jak prosty CASE wyrażenie.

Przypomnisz to sobie w naszym prostym CASE wyrażenie, zaczęło się od CASE @animal , dlatego wiedzieliśmy, że WHEN wszystkie wyrażenia były oceniane względem wartości @animal .

Z wyszukiwanym CASE wyrażenie, nie zapewniamy wyrażenia wejściowego na początku w ten sposób. Zamiast tego każde WHEN wyrażenie zawiera wyrażenie logiczne, dla którego ma być oceniane.

Przykład bazy danych

Oto przykład, który pokazuje, jak CASE wyrażenie może być użyte w zapytaniu do bazy danych.

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;

Wynik:

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

W tym przykładzie użyto przeszukiwanego CASE wyrażenie do oceny wyników z Population kolumna City stół.

ELSE jest opcjonalne

ELSE argument jest opcjonalny. Jeśli pominiemy ELSE , a żaden z warunków nie jest wyzwalany, wynikiem jest NULL .

Oto, co się dzieje, gdy pominiemy ELSE klauzula z poprzedniego przykładu:

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;

Wynik:

+---------------+------------+-----------+
| 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 w UPDATE Oświadczenie

Dodajmy kolumnę do City tabela z poprzedniego przykładu:

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

SELECT * FROM City
LIMIT 10;

Oto jak teraz wygląda:

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

Nie wstawiliśmy żadnych danych do nowego Size kolumna, więc zwraca NULL w każdym rzędzie.

Możemy teraz użyć CASE wyrażenie do aktualizacji Size kolumna z wartością zależną od wartości w Population kolumna:

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

Teraz wybierzmy dane z tabeli:

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

Wynik:

+------+---------------+-------------+---------------+------------+------------+
| 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 w INSERT Oświadczenie

Załóżmy, że mamy następującą tabelę w bazie danych SQL Server:

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

Wstawmy nowy wiersz do tej tabeli. Ale użyjmy CASE wyrażenie do wstawienia odpowiedniej wartości do Dinner kolumna, w zależności od wartości w GoodDog kolumna:

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

Tutaj CASE wyrażenie oceniło wartość zmiennej, którą właśnie ustawiliśmy, a następnie wstawił odpowiednią wartość do Dinner kolumna.

Teraz sprawdźmy ponownie tabelę:

SELECT * FROM Dogs;

Wynik:

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

Widzimy, że odpowiednia wartość znajduje się w Dinner kolumna.

CASE w ORDER BY Klauzula

CASE wyrażenie może być użyte w dowolnej instrukcji lub klauzuli, która zezwala na prawidłowe wyrażenie. Dlatego możesz go używać w instrukcjach takich jak SELECT , UPDATE , DELETE i SET oraz w klauzulach, takich jak IN , WHERE , ORDER BY , GROUP BY i HAVING .

Korzystanie z CASE wyrażenie w ORDER BY instrukcji Klauzula może być przydatna, gdy chcesz zrobić specjalny wyjątek dla pewnych wartości podczas porządkowania wyników.

Załóżmy, że uruchamiamy następujące zapytanie w tabeli zawierającej gatunki muzyczne.

SELECT Genre 
FROM Genres
ORDER BY Genre ASC;

Wynik:

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

Tutaj sortujemy wyniki według Genre kolumna w porządku rosnącym.

To jest w porządku, z wyjątkiem jednej rzeczy. Gatunek o nazwie Other . Czy nie byłoby miło, gdybyśmy mogli przenieść Other? na sam dół?

Możemy to osiągnąć za pomocą CASE wyrażenie, biorąc powyższe zapytanie i modyfikując je w następujący sposób.

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

Wynik:

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

COALESCE() i NULLIF() Funkcje

W zależności od scenariusza możemy użyć funkcji takich jak COALESCE() i NULLIF() jako skrót, zamiast używania CASE wyrażenie.

Te dwie funkcje są standardem SQL i działają w następujący sposób:

NULLIF (V1, V2)

Jest odpowiednikiem:

CASE WHEN V1=V2 THEN NULL ELSE V1 END

Oraz:

COALESCE (V1, V2)

Jest odpowiednikiem:

CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END

Również:

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

Jest odpowiednikiem:

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

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak dołączyć do trzech stołów według wymownego modelu laravel

  2. Konfigurowanie zdalnego połączenia z bazą danych MySQL

  3. Jak zainstalować phpMyAdmin na zarządzanych kontach hostingowych

  4. Usuwanie zduplikowanych wierszy z tabeli

  5. Replikacja MySQL i przełączanie awaryjne oparte na GTID — szczegółowe informacje o błędnych transakcjach