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
CASEwyrażenie - Przeszukano
CASEwyraż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.