Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Wyrażenie CASE programu SQL Server

W SQL Server CASE T-SQL wyrażenie to wyrażenie skalarne, które zwraca wartość opartą na logice warunkowej. Ocenia listę warunków i zwraca wartość w oparciu o wynik tych warunków.

W pewnym sensie SQL Server CASE wyrażenie jest podobne do IF...ELSE . Jednak CASE umożliwia sprawdzenie wielu warunków, podczas gdy IF...ELSE nie.

Również w SQL Server, IF...ELSE jest słowem kluczowym w języku kontroli przepływu, podczas gdy CASE nie jest. CASE wyrażenie nie może być używane do sterowania przepływem wykonywania instrukcji T-SQL, bloków instrukcji, funkcji zdefiniowanych przez użytkownika i procedur składowanych.

Dwie formy wyrażenia CASE

Istnieją dwie formy CASE wyrażenie w SQL Server:

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

Wyjaśniono je na poniższych przykładach.

Formularz 1 – proste wyrażenie CASE

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

Oto podstawowy przykład pokazujący, jak CASE wyrażenie działa w SQL Server.

DECLARE @stock_ticker varchar(4) = 'V';

SELECT Company =  
    CASE @stock_ticker  
        WHEN 'AAPL' THEN 'Apple'
        WHEN 'FB' THEN 'Facebook'
        WHEN 'V' THEN 'Visa'
        ELSE 'Not in the portfolio'  
    END

Wynik:

+-----------+
| Company   |
|-----------|
| Visa      |
+-----------+

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 symbol giełdowy V pasuje do trzeciego WHEN wyrażenie i wyrażenie dostarczone przez THEN jest zwracany.

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

    CASE @stock_ticker  
        WHEN 'AAPL' THEN 'Apple'
        WHEN 'FB' THEN 'Facebook'
        WHEN 'MA' THEN 'Mastercard'
        WHEN 'V' THEN 'Visa'
        ELSE 'Not in the portfolio'  
    END

Jaki CASE robi to, sprawdza wartość każdego WHEN wyrażenie w stosunku do wyrażenia wejściowego. W moim przykładzie @stock_ticker zmienna jest wyrażeniem wejściowym. Dlatego sprawdza wartość każdego WHEN wyrażenie na @stock_ticker zmienna.

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

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

Formularz 2 – Przeszukiwane wyrażenie CASE

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

Oto przykład przeszukiwanego CASE wyrażenie.

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        ELSE 'Expensive'  
    END

Wynik:

+-----------------+
| Affordability   |
|-----------------|
| Expensive       |
+-----------------+

Przeszukany 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 @stock_ticker , dlatego wiedzieliśmy, że WHEN wszystkie wyrażenia były oceniane względem wartości @stock_ticker .

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 WideWorldImporters;
SELECT 
    CityName AS [City], 
    LatestRecordedPopulation AS [Population], 
    Size =  
      CASE 
         WHEN LatestRecordedPopulation < 2000000 THEN 'Small City'  
         WHEN LatestRecordedPopulation >= 2000000 AND LatestRecordedPopulation < 3000000 THEN 'Big City' 
         ELSE 'Really Big City'
      END 
FROM Application.Cities
WHERE LatestRecordedPopulation > 1000000;

Wynik:

+--------------+--------------+-----------------+
| City         | Population   | Size            |
|--------------+--------------+-----------------|
| Brooklyn     | 2565635      | Big City        |
| Chicago      | 2695598      | Big City        |
| Dallas       | 1197816      | Small City      |
| Houston      | 2099451      | Big City        |
| Los Angeles  | 3792621      | Really Big City |
| Manhattan    | 1619090      | Small City      |
| New York     | 8175133      | Really Big City |
| Philadelphia | 1526006      | Small City      |
| Phoenix      | 1445632      | Small City      |
| Queens       | 2272771      | Big City        |
| San Antonio  | 1327407      | Small City      |
| San Diego    | 1307402      | Small City      |
| The Bronx    | 1408473      | Small City      |
+--------------+--------------+-----------------+

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

Typy danych

W SQL Server typ danych wyrażenia wejściowego i WHEN wyrażenia muszą być takie same lub muszą być niejawną konwersją.

Oto, co się stanie, jeśli nie są:

DECLARE @stock_ticker varchar(4) = 'V';

SELECT Company =  
      CASE @stock_ticker  
         WHEN 1 THEN 'Apple'
         WHEN 2 THEN 'Facebook'
         WHEN 3 THEN 'Mastercard'
         WHEN 4 THEN 'Visa'
         ELSE 'Not in the portfolio'  
      END

Wynik:

Msg 245, Level 16, State 1, Line 3
Conversion failed when converting the varchar value 'V' to data type int.

Kolejność oceny

T-SQL CASE wyrażenie ocenia swoje warunki sekwencyjnie i zatrzymuje się na pierwszym warunku, którego warunek jest spełniony.

Aby to zademonstrować, użyjmy wielu opcji WHEN wyrażenia, które mają tę samą wartość:

DECLARE @stock_ticker varchar(4) = 'V';

SELECT Company =  
    CASE @stock_ticker  
        WHEN 'V' THEN 'Visa 1'
        WHEN 'V' THEN 'Visa 2'
        WHEN 'V' THEN 'Visa 3'
        ELSE 'Not in the portfolio'  
    END

Wynik:

+-----------+
| Company   |
|-----------|
| Visa 1    |
+-----------+

W tym przypadku zatrzymał się przy pierwszym WHEN wyrażenie.

Może wystąpić sporadyczny scenariusz, w którym wyrażenie jest oceniane przed CASE wyrażenie otrzymuje wyniki wyrażenia jako dane wejściowe. W takich sytuacjach możesz skończyć z błędem. Może się tak zdarzyć, jeśli dodasz wyrażenie agregujące jako WHEN wyrażenie.

Z tego powodu firma Microsoft zaleca, aby:

Powinieneś polegać tylko na kolejności oceny warunków WHEN dla wyrażeń skalarnych (w tym nieskorelowanych podzapytań zwracających skalary), a nie dla wyrażeń agregujących.

INNE jest opcjonalne

ELSE argument jest opcjonalny. Dlatego moglibyśmy przepisać nasz przykład „przystępności cenowej” w następujący sposób:

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        WHEN @price >= 500 THEN 'Expensive'
    END    

Wynik:

+-----------------+
| Affordability   |
|-----------------|
| Expensive       |
+-----------------+

Pamiętaj jednak, że możesz skończyć z NULL jeśli pominiesz ELSE argument.

Poniższy przykład daje wynik NULL :

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
    END    

Wynik:

+-----------------+
| Affordability   |
|-----------------|
| NULL            |
+-----------------+

W takich przypadkach zawsze możemy dodać ELSE argument, na wszelki wypadek (przepraszam za kalambur!):

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
        ELSE 'Unknown'
    END  

Wynik:

+-----------------+
| Affordability   |
|-----------------|
| Unknown         |
+-----------------+

Trzeba przyznać, że ten przykład jest prawdopodobnie nieco wymyślny. W końcu nie ma potrzeby ograniczania „drogo”. Jeśli coś jest drogie poniżej 1000 USD, jest również drogie, jeśli przekracza 1000 USD.

Ale chodzi o to, że możesz użyć ELSE złapać wszystko, co nie jest objęte WHEN wyrażenie/s.

Zagnieżdżone wyrażenia CASE

Możesz zagnieździć CASE wyrażenia, jeśli są wymagane.

DECLARE @price int, @on_sale bit;
SET @price = 1500;
SET @on_sale = 1;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 THEN 
            CASE @on_sale
                WHEN 0 THEN 'Expensive (but it''s not currently on sale)' 
                WHEN 1 THEN 'Expensive (and it''s already on sale!)'
            END
    END

Wynik:

+---------------------------------------+
| Affordability                         |
|---------------------------------------|
| Expensive (and it's already on sale!) |
+---------------------------------------+

Należy jednak pamiętać, że tylko 10 poziomów zagnieżdżenia jest dozwolonych dla CASE wyrażenia w SQL Server. Jeśli spróbujesz zagnieździć więcej niż 10 poziomów, pojawi się błąd.

SPRAWA w klauzuli ORDER BY

Jak wspomniano, T-SQL 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 .

Używanie 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 MusicGenres
ORDER BY Genre ASC;

Wynik:

+---------+
| Genre   |
|---------|
| Blues   |
| Country |
| Hip Hop |
| Jazz    |
| Metal   |
| Other   |
| Pop     |
| 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 Inne . Czy nie byłoby miło, gdybyśmy mogli przenieść Inne 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 MusicGenres
ORDER BY 
    CASE Genre
        WHEN 'Other' THEN 1
        ELSE 0
    END
    ASC, Genre ASC;

Wynik:

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

CASE w instrukcji UPDATE

Oto przykład użycia CASE wyrażenie w UPDATE oświadczenie.

Załóżmy, że mamy następującą tabelę:

+---------+-----------+-----------+----------+
| DogId   | DogName   | GoodDog   | Dinner   |
|---------+-----------+-----------+----------|
| 1       | Fetch     | 1         | NULL     |
| 2       | Fluffy    | 0         | NULL     |
| 3       | Wag       | 0         | NULL     |
| 1001    | Brian     | 1         | NULL     |
| 1002    | Rambo     | 0         | NULL     |
| 1003    | BamBam    | 1         | NULL     |
+---------+-----------+-----------+----------+

Niedawno dodaliśmy Dinner kolumna i nadal jest NULL , czekając na wstawienie wartości.

Ale wstawiane wartości będą zależeć od wartości GoodDog kolumna.

Moglibyśmy użyć CASE wyrażenie w takim scenariuszu.

UPDATE Dogs 
SET Dinner = 
    CASE GoodDog
        WHEN 1 THEN 'Sunday Roast'
        ELSE 'Airline food'
    END

SELECT * FROM Dogs;

Wynik:

+---------+-----------+-----------+--------------+
| DogId   | DogName   | GoodDog   | Dinner       |
|---------+-----------+-----------+--------------|
| 1       | Fetch     | 1         | Sunday Roast |
| 2       | Fluffy    | 0         | Airline food |
| 3       | Wag       | 0         | Airline food |
| 1001    | Brian     | 1         | Sunday Roast |
| 1002    | Rambo     | 0         | Airline food |
| 1003    | BamBam    | 1         | Sunday Roast |
+---------+-----------+-----------+--------------+

CASE w instrukcji INSERT

Możemy wziąć tabelę z powyższego przykładu i wstawić nową wartość.

I znowu możemy skorzystać z CASE wyrażenie do wstawienia odpowiedniej wartości do Dinner 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
    );

SELECT * FROM Dogs;

Wynik:

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

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

Czy jest to instrukcja CASE czy wyrażenie CASE?

W SQL wiele rzeczy jest określanych jako „oświadczenie”, podczas gdy w rzeczywistości jest to coś innego. Wydaje się, że dotyczy to również T-SQL „CASE oświadczenie”.

Chociaż często jest określany jako CASE oświadczenie, lepiej nazywać to CASE wyrażenie . Tak też odnosi się do tego dokumentacja Microsoft.

W SQL Server, zamiast być samą instrukcją, CASE może być użyty w dowolnej instrukcji lub klauzuli, która zezwala na prawidłowe wyrażenie. Wyrażenie to kombinacja symboli i operatorów, które są oceniane w celu uzyskania pojedynczej wartości danych.

Jednak niektóre DBMS rozróżniają CASE oświadczenie i CASE wyrażenie i mają nieco inną składnię dla każdego. MySQL rozróżnia CASE oświadczenie i CASE operator, który jest zasadniczo taki sam jak CASE wyrażenie.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ustaw wartość początkową dla kolumny z autoinkrementacją

  2. TSQL - Dodaj kolumnę do wszystkich tabel w bazie danych [Przykład kursora]

  3. Jak zaimplementować LIMIT z SQL Server?

  4. Jak wstawić JSON do tabeli w SQL Server

  5. Jak zwrócić wszystkie niezaufane ograniczenia kluczy obcych w programie SQL Server (przykład T-SQL)