sql >> Databáze >  >> RDS >> Sqlserver

SQL Server CASE výraz

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 je NULL , č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 do Dinner 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 do Dinner 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 jej CASE 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 a CASE výraz a mají pro každý trochu jinou syntaxi. MySQL rozlišuje mezi CASE a CASE operátor, který je v podstatě stejný jako CASE výraz.


  1. INITCAP() – Převod na počáteční velká písmena v PostgreSQL

  2. Jak se připojit k SQL Serveru s ověřováním Windows z Node.JS pomocí modulu mssql

  3. Příklady UTC_TIMESTAMP() – MySQL

  4. Spustit odložený trigger pouze jednou na řádek v PostgreSQL