V SQL Server, T-SQL CASE
výraz je skalární výraz, který vrací hodnotu založenou na podmíněné logice. Vyhodnotí seznam podmínek a vrátí hodnotu na základě výsledku těchto podmínek..
V některých ohledech SQL Server CASE
výraz je podobný IF...ELSE
. Nicméně CASE
umožňuje zkontrolovat více podmínek, zatímco IF...ELSE
ne
Také v SQL Server, IF...ELSE
je klíčové slovo jazyka kontroly toku, zatímco CASE
není. CASE
výraz nelze použít k řízení toku provádění příkazů T-SQL, bloků příkazů, uživatelem definovaných funkcí a uložených procedur.
Dvě formy vyjádření CASE
Existují dvě formy CASE
výraz v SQL Server:
- Jednoduchý
CASE
výraz - Hledali jste
CASE
výraz
Ty jsou vysvětleny na příkladech níže.
Formulář 1 – Jednoduchý výraz CASE
Jednoduchý CASE
výraz porovnává výraz se sadou jednoduchých výrazů a určuje výsledek.
Zde je základní příklad demonstrující, jak CASE
výraz funguje na serveru SQL.
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
Výsledek:
+------------+| Společnost ||------------|| Visa |+-----------+
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ě burzovní ticker V
odpovídá třetímu WHEN
výraz a výraz poskytnutý THEN
je vráceno.
Aby bylo jasno, skutečný CASE
výraz je tato část:
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
Jaký CASE
ano, kontroluje hodnotu každého WHEN
výraz proti vstupnímu výrazu. V mém příkladu @stock_ticker
proměnná je vstupní výraz. Proto kontroluje hodnotu každého WHEN
výraz proti @stock_ticker
proměnná.
Když/pokud najde shodu, vrátí výraz poskytnutý THEN
.
Můj příklad používá tři WHEN
výrazů, ale mohlo to být více a mohlo to být méně, podle mých požadavků.
Formulář 2 – Vyhledaný výraz CASE
Hledaný CASE
expression vyhodnotí sadu booleovských výrazů k určení výsledku.
Zde je příklad hledaného CASE
výraz.
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
ELSE 'Expensive'
END
Výsledek:
+------------------+| Cenová dostupnost ||------------------|| Drahé |+-----------------+
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
@stock_ticker
, a proto jsme věděli, že WHEN
všechny výrazy byly hodnoceny podle hodnoty @stock_ticker
.
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 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;
Výsledek:
+--------------+--------------+---------------- -+| Město | Populace | Velikost ||--------------+--------------+------------------ || Brooklyn | 2565635 | Velké město || Chicago | 2695598 | Velké město || Dallas | 1197816 | Malé město || Houston | 2099451 | Velké město || Los Angeles | 3792621 | Opravdu velké město || Manhattan | 1619090 | Malé město || New York | 8175133 | Opravdu velké město || Philadelphia | 1526006 | Malé město || Fénix | 1445632 | Malé město || Královny | 2272771 | Velké město || San Antonio | 1327407 | Malé město || San Diego | 1307402 | Malé město || Bronx | 1408473 | Malé město |+--------------+--------------+---------------- -+
Tento příklad používá hledaný CASE
výraz pro vyhodnocení výsledků z LatestRecordedPopulation
ve sloupci Application.Cities
stůl.
Typy dat
V SQL Server datový typ vstupního výrazu a WHEN
výrazy musí být stejné nebo musí jít o implicitní konverzi.
Pokud tomu tak není, stane se toto:
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
Výsledek:
Zpráva 245, úroveň 16, stav 1, řádek 3 Převod se nezdařil při převodu hodnoty varchar 'V' na datový typ int.
Pořadí hodnocení
CASE
T-SQL výraz vyhodnotí své podmínky postupně a zastaví se s první podmínkou, jejíž podmínka je splněna.
Abychom to demonstrovali, použijme více WHEN
výrazy, které sdílejí stejnou hodnotu:
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
Výsledek:
+------------+| Společnost ||------------|| Visa 1 |+-----------+
V tomto případě se zastavil na prvním WHEN
výraz.
Může nastat příležitostný scénář, kdy je výraz vyhodnocen před CASE
výraz přijímá výsledky výrazu jako svůj vstup. V takových scénářích můžete skončit s chybou. K tomu může dojít, pokud jako WHEN
zahrnete agregovaný výraz výraz.
Z tohoto důvodu společnost Microsoft doporučuje:
Měli byste se spoléhat pouze na pořadí vyhodnocení podmínek WHEN pro skalární výrazy (včetně nekorelovaných dílčích dotazů, které vracejí skaláry), nikoli pro agregované výrazy.
ELSE je volitelné
ELSE
argument je volitelný. Proto bychom mohli náš příklad „cenové dostupnosti“ přepsat následovně:
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
Výsledek:
+------------------+| Cenová dostupnost ||------------------|| Drahé |+-----------------+
Mějte však na paměti, že můžete skončit s NULL
pokud vynecháte ELSE
argument.
Výsledkem následujícího příkladu je 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
Výsledek:
+------------------+| Cenová dostupnost ||------------------|| NULL |+-----------------+
V takových případech můžeme vždy přidat ELSE
argument, jen pro případ (omlouvám se za slovní hříčku!):
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
Výsledek:
+------------------+| Cenová dostupnost ||------------------|| Neznámý |+-----------------+
Nutno uznat, že tento příklad je pravděpodobně trochu vymyšlený. Koneckonců, není třeba limitovat „drahé“. Pokud je něco drahé pod 1000 USD, pak je to také drahé, pokud je to nad 1000 USD.
Jde ale o to, že můžete použít ELSE
zachytit vše, co není zahrnuto v WHEN
výraz/s.
Vnořené výrazy typu CASE
Můžete vnořit CASE
výrazy v případě potřeby.
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
Výsledek:
+---------------------------------------+| Cenová dostupnost ||--------------------------------------|| Drahé (a už je v prodeji!) |+--------------------------------------- +
Je však důležité si uvědomit, že pro CASE
je povoleno pouze 10 úrovní vnoření výrazy na serveru SQL Server. Pokud se pokusíte vnořit více než 10 úrovní, zobrazí se chyba.
CASE v klauzuli ORDER BY
Jak již bylo zmíněno, T-SQL CASE
výraz lze použít v libovolném 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 MusicGenres
ORDER BY Genre ASC;
Výsledek:
+----------+| Žánr ||----------|| Blues || Země || Hip Hop || Jazz || Kov || Ostatní || Pop || 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 Ostatní . Nebylo by hezké, kdybychom mohli přesunout Jiné 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 MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Výsledek:
+----------+| Žánr ||----------|| Blues || Země || Hip Hop || Jazz || Kov || Pop || Rap || Rock || Ostatní |+---------+
CASE ve výpisu UPDATE
Zde je příklad použití CASE
výraz v UPDATE
prohlášení.
Předpokládejme, že máme následující tabulku:
+---------+-----------+-----------+----------+| DogId | Jméno psa | Hodný pes | Večeře ||---------+-----------+-----------+----------|| 1 | Načíst | 1 | NULL || 2 | Načechraný | 0 | NULL || 3 | Wag | 0 | NULL || 1001 | Brian | 1 | NULL || 1002 | Rambo | 0 | NULL || 1003 | BamBam | 1 | NULL |+---------+-----------+-----------+----------+Nedávno jsme přidali
Dinner
a stále jeNULL
, čeká na vložení hodnot.Ale hodnoty, které mají být vloženy, budou záviset na hodnotě
GoodDog
sloupec.Mohli bychom použít
CASE
výraz v takovém scénáři.UPDATE Dogs SET Dinner = CASE GoodDog WHEN 1 THEN 'Sunday Roast' ELSE 'Airline food' END SELECT * FROM Dogs;
Výsledek:
+---------+-----------+-----------+------------ --+| DogId | Jméno psa | Hodný pes | Večeře ||---------+-----------+-----------+-------------- -|| 1 | Načíst | 1 | Nedělní pečeně || 2 | Načechraný | 0 | Letecké jídlo || 3 | Wag | 0 | Letecké jídlo || 1001 | Brian | 1 | Nedělní pečeně || 1002 | Rambo | 0 | Letecké jídlo || 1003 | BamBam | 1 | Nedělní pečeně |+---------+-----------+-----------+------------- --+CASE v příkazu INSERT
Můžeme vzít tabulku z výše uvedeného příkladu a vložit novou hodnotu.
A opět můžeme využít výhod
CASE
výraz pro vložení příslušné hodnoty doDinner
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 ); SELECT * FROM Dogs;
Výsledek:
+---------+-----------+-----------+------------ --+| DogId | Jméno psa | Hodný pes | Večeře ||---------+-----------+-----------+-------------- -|| 1 | Načíst | 1 | Nedělní pečeně || 2 | Načechraný | 0 | Letecké jídlo || 3 | Wag | 0 | Letecké jídlo || 1001 | Brian | 1 | Nedělní pečeně || 1002 | Rambo | 0 | Letecké jídlo || 1003 | BamBam | 1 | Nedělní pečeně || 1004 | Líný | 0 | Letecká strava |+---------+-----------+-----------+------------- --+Tentokrát
CASE
výraz vyhodnotil hodnotu proměnné, kterou jsme právě nastavili, a poté vložil příslušnou hodnotu doDinner
sloupec.Je to příkaz CASE nebo výraz CASE?
V SQL se spousta věcí označuje jako „příkaz“, i když ve skutečnosti jde o něco jiného. Zdá se, že to platí i pro T-SQL „
CASE
prohlášení“.I když se tomu často říká
CASE
je přesnější nazývat jejCASE
výraz . Takto se na něj odkazuje také dokumentace společnosti Microsoft.V SQL Server, spíše než být samotný příkaz,
CASE
lze použít v jakémkoli příkazu nebo klauzuli, která umožňuje platný výraz. Výraz je kombinací symbolů a operátorů, které jsou vyhodnoceny za účelem získání jedné datové hodnoty.Některé DBMS však rozlišují mezi
CASE
aCASE
výraz a mají pro každý trochu jinou syntaxi. MySQL rozlišuje meziCASE
aCASE
operátor, který je v podstatě stejný jakoCASE
výraz.