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ý
CASEvýraz - Hledali jste
CASEvý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
Dinnera stále jeNULL, čeká na vložení hodnot.Ale hodnoty, které mají být vloženy, budou záviset na hodnotě
GoodDogsloupec.Mohli bychom použít
CASEvý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
CASEvýraz pro vložení příslušné hodnoty doDinnersloupec.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
CASEvýraz vyhodnotil hodnotu proměnné, kterou jsme právě nastavili, a poté vložil příslušnou hodnotu doDinnersloupec.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 „
CASEprohlášení“.I když se tomu často říká
CASEje přesnější nazývat jejCASEvýraz . Takto se na něj odkazuje také dokumentace společnosti Microsoft.V SQL Server, spíše než být samotný příkaz,
CASElze 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
CASEaCASEvýraz a mají pro každý trochu jinou syntaxi. MySQL rozlišuje meziCASEaCASEoperátor, který je v podstatě stejný jakoCASEvýraz.