Příkaz SQL CASE vyhodnocuje a vrací výsledky na základě konkrétních hodnot, predikátů a podmínek podle definované logiky. Předpokládejme například, že máte tabulku voličů s následujícími podrobnostmi:
- ID voliče
- Jméno
- DOB
Pokud byste hledali logiku ohledně způsobilosti k hlasování, záviselo by to na hodnotách ve sloupci DOB.
Pokud je věk voliče vyšší než 18, má právo volit.
Podívejme se na další příklad. Mnohokrát ukládáme hodnoty sloupců v bitech 1 nebo 0. Řekněme, že ukládáte hodnoty pro dostupnost produktu jako 1 nebo 0. Například:
- 1 =Produkt je dostupný
- 0 =Produkt není skladem
Pokud se podíváme na databázovou perspektivu, je dobrým zvykem používat zkratky nebo bity všude, kde je to možné. Je to užitečné pro optimalizátor dotazů SQL Server při přípravě optimalizovaného plánu provádění. Ale z pohledu aplikace koncový uživatel tyto hodnoty nevyžaduje. Zákazníci se jen potřebují podívat, zda je produkt dostupný nebo ne.
Na obrázku níže vidíme perspektivu databáze i aplikace.
Co dělá příkaz SQL CASE?
Příkaz CASE v SQL Server vyhodnotí výraz a vrátí hodnotu na základě definovaných podmínek. Proto v předchozím příkladu příkazy CASE fungují tak, jak je uvedeno níže.
Na vyšší úrovni je syntaxe příkazu SQL CASE uvedena níže. Zde jsme specifikovali několik podmínek. SQL Server vyhodnocuje podmínky postupně. Jakmile se podmínka úspěšně vyhodnotí, zastaví se vyhodnocování zbývajících podmínek. Pokud není splněna žádná z podmínek, můžeme použít volitelný příkaz ELSE k vrácení výchozí hodnoty. Pokud máme například ve sloupci dostupnosti hodnotu jinou než 0 a 1, získáte výstup z bloku kódu ELSE. Vyžaduje alespoň jednu sadu bloků WHEN a THEN. Příkaz CASE musí končit blokem END.
Pojďme prozkoumat příkaz SQL CASE na různých příkladech.
Poznámka:V tomto článku používáme ukázkovou databázi společnosti Microsoft AdventureWorks. Jeho zálohu si můžete stáhnout z Microsoft Docs.
Příkaz SELECT s jednoduchým výrazem CASE
V tomto typu příkazu CASE používáme výrazy kontroly rovnosti. Následující dotaz implementuje jednoduchý výraz CASE.
- Pokud je hodnota v [SalariedFlag] 1, zobrazí se Aktivní zaměstnanec
- U všech ostatních hodnot zobrazí výstup jako Neaktivní zaměstnanec
VYBERTE TOP 5 Nationalidnumber ,CASE salariedflagWHEN 1 THEN 'Active Employee'ELSE 'Inactive Employee'END AS [Salaried Flag]OD [AdventureWorks2019].[HumanResources].[zaměstnanec]
Pro příkaz CASE můžeme zadat více podmínek.
VYBERTE TOP 5 Nationalidnumber ,CASE salariedflagWHEN 1 THEN 'Active Employee'WHEN 0 THEN 'Inactive Employee'ELSE 'Invalid Value'END AS [Salaried Flag]OD [AdventureWorks2019].[HumanResources].[zaměstnanec]
Standardizace dat pomocí příkazů SQL CASE
Obvykle používáme zkratky pro ukládání hodnot do SQL tabulek. Standardní zkratky jsou pohlaví, kódy zemí, stav manželství, oblíbené názvy produktů atd.
Předpokládejme, že zadáme zkratky pro ukládání pohlaví zaměstnanců. Nyní by naše aplikace měla zobrazovat výsledky bez jakýchkoli zkratek.
Příkazy SQL CASE pomáhají standardizovat výstup pro definovaná kritéria. V níže uvedeném dotazu používáme následující podmínky:
- Pokud je hodnota pohlaví M , zobrazte jej jako Muž
- Pokud je hodnota pohlaví F , zobrazte jej jako Žena
- U všech ostatních hodnot zobrazte hodnotu Neplatné Hodnota
VYBERTE ODLIŠNÝ PŘÍPAD genderWHEN 'M' THEN 'Male'WHEN 'F' THEN 'Female'ELSE 'Invalid Value'END AS GenderFROM AdventureWorks2019.HumanResources.Employee
Vyhledávané příkazy CASE
V hledaném příkazu CASE zadáváme místo přímých hodnot výraz CASE. Jakmile hodnota výrazu vyhodnotí a splní podmínku v klauzuli WHEN, vrátí se její odpovídající hodnota.
Podívejte se na níže uvedený SQL dotaz. Zde jsme definovali výrazy v klauzuli WHEN pro [Cenová cena]. Označuje, že cena produktu je 250 USD a je označena jako elektronika.
SELECT ProductNumber, Name, [Product category] =CASE WHEN ListPrice =0 THEN 'Vyprodané položky' WHEN ListPrice> 0 a ListPrice<=100 THEN 'Spotřební zboží' WHEN ListPrice>100 a ListPrice <=500 THEN ' Elektronické položky' KDYŽ Katalogová cena>500 a Katalogová cena <1500 POTOM 'Luxusní položky' JINAK 'Položky navíc' KONČÍ OD VÝROBY. Řazení produktu podle Katalogové ceny desc
U výše uvedeného příkladu pohlaví můžeme přepsat příkaz SQL CASE pro zkratky pohlaví pomocí hledaných příkazů typu case.
VYBERTE DISTINCT CASE WHEN Gender='M' THEN 'Male'WHEN Gender='F' THEN 'Female'ELSE 'Invalid Value'END AS GenderFROM AdventureWorks2019.HumanResources.Employee
Použití příkazů CASE s klauzulí ORDER BY
SQL dotazy používají klauzuli ORDER BY pro řazení dat ve vzestupném nebo sestupném pořadí. Příkazy CASE můžete použít ve spojení s klauzulí ORDER BY. Předpokládejme, že z tabulky produktů načteme [ProductName] a [ListPrice]. Chceme seřadit výsledky následujícím způsobem:
- Pokud je katalogová cena produktu nižší než 2 000, chcete výsledek ve výchozím řazení, tj. vzestupně.
- Pokud je katalogová cena produktu vyšší než 2 000, výsledkem řazení klauzule ORDER BY bude sestupné pořadí
V tomto dotazu používáme k implementaci logiky dva příkazy SQL CASE.
SELECT Name,ListPriceFROM Production.ProductORDER BY CASEWHEN ListPrice<=2000 THEN ListPrice END ,CASE WHEN ListPrice>2000 THEN ListPrice END DESC
V níže uvedeném výstupu dotazu můžete ověřit řazení dat v sestupném i vzestupném pořadí.
V dalším příkladu předpokládejme, že chceme seřadit data v tabulce zaměstnanců na základě následující podmínky:
- U aktivních zaměstnanců (aktuální příznak =1) by údaje měly seřadit sloupec data přijetí
- U neaktivních zaměstnanců by měl seřadit data podle hodnot ve sloupci data narození
SELECT NationalIDNumber,JobTitle,Hiredate,BirthDate, currentflagFROM AdventureWorks2019.HumanResources.Employee OBJEDNEJTE PODLE VELIKOSTÍ AKTUÁLNÍ VLAJKA KDYŽ 1 PAK NÁJMUDatum jinak Konec data narození
Ve výstupu dotazu můžeme ověřit pořadí řazení dat definované klauzulí ORDER BY a příkazy CASE.
Příkaz CASE v SQL a agregačních funkcích
Agregační funkce v SQL Server provádějí výpočty a vracejí jedinou hodnotu. Příklady agregačních funkcí jsou MIN, MAX, COUNT, ABG a CHECKSUM.
Předpokládejme, že chceme získat počet přijatých zaměstnanců za každý rok od roku 2007 do roku 2010. Měl by zobrazovat výsledky v následujícím formátu:
Pro tento účel používáme agregační funkci COUNT v SQL Server.
- Nejprve funkce SQL DATEPART filtruje data podle roku. Například DATEPART(YY, Hiredate)=2007 filtruje data za rok 2007.
- Potom použijeme příkaz CASE k vrácení 1, pokud je rok 2007.
- Funkce agregace počtu počítá záznamy a zobrazuje výsledky.
- Podobně dotaz funguje po zbývající roky.
SELECT Count(CASEWHEN Datepart(yy, recruitdate) =2007 THEN 1ELSE NULLEND) AS [2007Hires],Count(CASEWHEN Datepart(yy, recruitdate) =2008 THEN 1ELSE NULLEND AS [2008HiresWHEN(yCpart) , recruitdate) =2009 THEN 1ELSE NULLEND) AS [2009Hires],Count(CASEWHEN Datepart(yy, recruitdate) =2009 THEN 1ELSE NULLEND) AS [2010Hires]FROM AdventureWorks2019.HumaneeePodobně řekněme, že chceme použít agregační funkci GROUP BY k seskupení řádků se stejnou kategorií produktu. Můžeme zadat příkaz CASE v SQL pro seřazení dat ze seskupené výsledkové sady.
SELECT [Kategorie produktu] =CASEWHEN listprice =0 THEN 'Položky vyprodané'WHEN listprice> 0AND listprice <=100 THEN 'Spotřební zboží'WHEN listprice> 100AND listprice <=500 THEN 'Položky elektroniky A>500 listing katalogová cena <1500 POTOM 'Luxusní položky'ELSE 'Položky navíc'KONEC,Min.(katalogová cena) JAKO Min.Cena,Max(katalogová) JAKO Max.Cena,Počet(katalogová) JAKO PočetproduktůZ výroby.SKUPINA produktů PODLE PŘÍPADU, KDYŽ katalogová cena =0 POTOM 'Položky vyprodané' KDYŽ katalogová cena> 0AND katalogová cena <=100 POTOM 'Spotřební zboží'WHEN katalogová cena> 100AND katalogová cena <=500 THEN 'Položky elektroniky'WHEN katalogová cena> 500AND katalogová cena <1500 POTOM 'Luxusní položky'POČET PRODUKTŮ DLE OBJEDNÁVKY EXTRA>Ve výše uvedeném dotazu používáme dva příkazy SQL CASE.
- První příkaz CASE kategorizuje data na základě výrazu definovaného v ceníkové ceně. Pomocí tohoto příkazu CASE rozdělíme produkty do následujících kategorií:
- Položky, které nejsou skladem
- Spotřební zboží
- Elektronické položky
- Luxusní zboží
- Ve druhém případě používáme agregační funkci GROUP BY k seskupení výsledku podle kategorie
- Výsledky dále seřadíme podle NumberOfProducts v sestupném pořadí
Zabránění chyby dělení nulou pomocí příkazů SQL CASE
Chyba dělení nulou nastane, pokud je hodnota jmenovatele nula. Pokud provedete tyto zlomky v SQL Server, dostanete chybu dělení nulou, jak je uvedeno níže.
Je vynikající praxí psát své dotazy tak, abyste se vyvarovali těchto běžných chyb. Abychom tomu zabránili, používáme zlomkovou logiku uvnitř příkazu CASE.
DECLARE @Student1 INTDECLARE @Student2 INTSET @Student1=100SET @Student2=0select CASE WHEN @Student2=0THEN NULLELSE @Student1/@Student2 end jako StudentMarksRatio
Náš dotaz jsme ochránili před chybou dělení nulou. Nyní, s upravenou logikou, pokud dostaneme nulu ve jmenovateli, dostanete ve výstupu NULL, jak je uvedeno níže.
Užitečné připomínky k příkazu SQL CASE
- Příkazy SQL CASE podporují až 10 úrovní vnoření
- Nemůžete řídit tok provádění příkazů, funkcí nebo procedur pomocí výrazů CASE
- Vždy byste měli používat blok ELSE, takže v případě nesplnění jakýchkoli podmínek získáte výchozí hodnotu
- Měli byste se vyhnout používání konfliktních podmínek v příkazu SQL CASE. Příkaz CASE funguje sekvenčně a přestane se vyhodnocovat s první úspěšnou podmínkou