Sdílet prostřednictvím


PŘÍPAD (Transact-SQL)

Platí pro:SQL ServerAzure SQL DatabaseSpravovaná instance Azure SQLAzure Synapse AnalyticsAnalytics Platform System (PDW)Koncový bod analýzy SQL v Microsoft FabricSklad v Microsoft FabricDatabáze SQL v Microsoft Fabric

Vyhodnotí seznam podmínek a vrátí jeden z více možných výsledných výrazů.

Výraz CASE má dva formáty:

  • JednoduchýCASE výraz porovná výraz se sadou jednoduchých výrazů a určí výsledek.

  • HledanýCASE výraz vyhodnotí sadu logických výrazů k určení výsledku.

Oba formáty podporují volitelný ELSE argument.

CASE lze použít v libovolném příkazu nebo klauzuli, která umožňuje platný výraz. Můžete například použít CASE v příkazech, jako SELECTjsou , UPDATEDELETEa SET, a v klauzulích, jako <select_list>jsou , IN, WHERE, ORDER BYa HAVING.

Transact-SQL konvence syntaxe

Syntax

Syntaxe PRO SQL Server, Azure SQL Database a Azure Synapse Analytics

-- Simple CASE expression:
CASE input_expression
     WHEN when_expression THEN result_expression [ ...n ]
     [ ELSE else_result_expression ]
END

-- Searched CASE expression:
CASE
     WHEN Boolean_expression THEN result_expression [ ...n ]
     [ ELSE else_result_expression ]
END

Syntaxe paralelního datového skladu

CASE
     WHEN when_expression THEN result_expression [ ...n ]
     [ ELSE else_result_expression ]
END

Arguments

input_expression

Výraz se vyhodnotí při použití jednoduchého CASE formátu. input_expression je libovolný platný výraz.

KDYŽ when_expression

Jednoduchý výraz, ke kterému se input_expression porovná při použití jednoduchého CASE formátu. when_expression je libovolný platný výraz. Datové typy input_expression a každý when_expression musí být stejný nebo musí být implicitní převod.

PAK result_expression

Výraz vrácený, když se input_expression rovná when_expression vyhodnotí na TRUEhodnotu , nebo Boolean_expression vyhodnotí jako TRUE. výsledek výrazu je libovolný platný výraz.

DALŠÍ else_result_expression

Výraz vrácený, pokud se nevyhodnocuje TRUEžádná operace porovnání . Pokud je tento argument vynechán a není vyhodnocena TRUEžádná operace porovnání , CASE vrátí hodnotu NULL. else_result_expression je libovolný platný výraz. Datové typy else_result_expression a všechny result_expression musí být stejné nebo musí být implicitní převod.

KDYŽ Boolean_expression

Logický výraz se vyhodnocuje při použití prohledáného CASE formátu. Boolean_expression je libovolný platný logický výraz.

Návratové typy

Vrátí typ nejvyšší priority ze sady typů v result_expressions a volitelné else_result_expression. Další informace naleznete v tématu Priorita datového typu.

Návratové hodnoty

Jednoduchý výraz CASE

Jednoduchý CASE výraz funguje porovnáním prvního výrazu s výrazem v každé WHEN klauzuli pro ekvivalenci. Pokud jsou tyto výrazy ekvivalentní, vrátí se výraz v THEN klauzuli.

  • Povoluje pouze kontrolu rovnosti.

  • V zadaném pořadí se vyhodnotí input_expression = when_expression pro každou WHEN klauzuli.

  • Vrátí result_expression prvního input_expression when_expression = , který se vyhodnotí jako .TRUE

  • Pokud se žádná input_expression when_expression = nevyhodnotíTRUE, databázový stroj SQL Serveru vrátí else_result_expression pokud ELSE je zadaná klauzule, nebo NULL pokud není zadána žádná ELSE klauzule.

Hledaný výraz CASE

  • Vyhodnotí v uvedeném pořadí Boolean_expression pro každou WHEN klauzuli.

  • Vrátí result_expression prvního Boolean_expression , který se vyhodnotí jako TRUE.

  • Pokud se žádná Boolean_expression nevyhodnotí TRUE, databázový stroj vrátí else_result_expression , pokud ELSE je zadaná klauzule, nebo NULL hodnotu, pokud není zadána žádná ELSE klauzule.

Remarks

SQL Server umožňuje pouze 10 úrovní vnoření ve CASE výrazech.

Výraz CASE se nedá použít k řízení toku provádění příkazů Transact-SQL, bloků příkazů, uživatelem definovaných funkcí a uložených procedur. Seznam metod řízení toku najdete v tématu Řízení toku.

Výraz CASE vyhodnocuje své podmínky postupně a zastavuje první podmínkou, jejíž podmínka je splněna. V některých situacích je výraz vyhodnocen před tím, než CASE výraz obdrží výsledky výrazu jako jeho vstup. Chyby při vyhodnocování těchto výrazů jsou možné. Agregační výrazy, které se zobrazují v WHEN argumentech výrazu CASE , se vyhodnocují jako první a pak se do výrazu CASE zadají. Například následující dotaz vytvoří při vytváření hodnoty agregace chybu dělicí nulou MAX . K tomuto kroku dochází před vyhodnocením výrazu CASE .

WITH Data (value)
AS (
    SELECT 0
    UNION ALL
    SELECT 1
    )
SELECT CASE
        WHEN MIN(value) <= 0 THEN 0
        WHEN MAX(1 / value) >= 100 THEN 1
        END
FROM Data;
GO

Měli byste záviset pouze na pořadí vyhodnocení podmínek skalárních WHEN výrazů (včetně nekomentovaných poddotazů, které vracejí skaláry), ne pro agregační výrazy.

Musíte také zajistit, aby alespoň jeden z výrazů v THEN klauzulích nebo ELSE klauzulích nebyl konstantou NULL . I když NULL je možné je vrátit z více výsledných výrazů, ne všechny z nich mohou být explicitně konstantou NULL . Pokud všechny výsledné výrazy používají konstantu NULL , vrátí se chyba 8133.

Examples

Ukázky kódu v tomto článku používají ukázkovou databázi AdventureWorks2025 nebo AdventureWorksDW2025, kterou si můžete stáhnout z domovské stránky Microsoft SQL Serveru pro ukázky a komunitní projekty .

A. Použití příkazu SELECT s jednoduchým výrazem CASE

SELECT V rámci příkazu umožňuje jednoduchý CASE výraz pouze kontrolu rovnosti. Neprovedou se žádná jiná porovnání. Následující příklad používá CASE výraz ke změně zobrazení kategorií produktové řady, aby byly srozumitelnější.

USE AdventureWorks2022;
GO

SELECT ProductNumber,
    Category = CASE ProductLine
        WHEN 'R' THEN 'Road'
        WHEN 'M' THEN 'Mountain'
        WHEN 'T' THEN 'Touring'
        WHEN 'S' THEN 'Other sale items'
        ELSE 'Not for sale'
        END,
    Name
FROM Production.Product
ORDER BY ProductNumber;
GO

B. Použití příkazu SELECT s hledaným výrazem CASE

SELECT Hledaný CASE výraz v rámci příkazu umožňuje nahradit hodnoty v sadě výsledků na základě porovnávaných hodnot. Následující příklad zobrazí ceníkovou cenu jako textový komentář na základě cenového rozsahu produktu.

USE AdventureWorks2022;
GO

SELECT ProductNumber,
    Name,
    "Price Range" = CASE
        WHEN ListPrice = 0 THEN 'Mfg item - not for resale'
        WHEN ListPrice < 50 THEN 'Under $50'
        WHEN ListPrice >= 50 AND ListPrice < 250 THEN 'Under $250'
        WHEN ListPrice >= 250 AND ListPrice < 1000 THEN 'Under $1000'
        ELSE 'Over $1000'
        END
FROM Production.Product
ORDER BY ProductNumber;
GO

C. Use CASE v klauzuli ORDER BY

Následující příklady používají CASE výraz v ORDER BY klauzuli k určení pořadí řazení řádků na základě dané hodnoty sloupce. V prvním příkladu se vyhodnotí hodnota ve SalariedFlag sloupci HumanResources.Employee tabulky. Zaměstnanci, kteří mají nastavenou SalariedFlag hodnotu 1, se vrátí v pořadí sestupně BusinessEntityID . Zaměstnanci, kteří mají nastavenou SalariedFlag hodnotu 0, se vrátí v pořadí BusinessEntityID vzestupně.

SELECT BusinessEntityID,
    SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag
        WHEN 1 THEN BusinessEntityID
        END DESC,
    CASE
        WHEN SalariedFlag = 0 THEN BusinessEntityID
        END;
GO

V druhém příkladu je sada výsledků seřazena podle sloupce TerritoryName , pokud se sloupec CountryRegionName rovná "Spojené státy" a podle CountryRegionName všech ostatních řádků.

SELECT BusinessEntityID,
    LastName,
    TerritoryName,
    CountryRegionName
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL
ORDER BY CASE CountryRegionName
        WHEN 'United States' THEN TerritoryName
        ELSE CountryRegionName
        END;
GO

D. Použijte CASE v příkazu UPDATE

Následující příklad používá CASE výraz v UPDATE příkazu k určení hodnoty, která je nastavena pro sloupec VacationHours pro zaměstnance s SalariedFlag nastavenou hodnotou 0. Při odečítání 10 hodin od VacationHours výsledků záporné hodnoty VacationHours se zvýší o 40 hodin; jinak VacationHours se zvýší o 20 hodin. Klauzule OUTPUT slouží k zobrazení hodnot před a po dovolené.

USE AdventureWorks2022;
GO

UPDATE HumanResources.Employee
SET VacationHours = (
        CASE
            WHEN ((VacationHours - 10.00) < 0) THEN VacationHours + 40
            ELSE (VacationHours + 20.00)
            END
        )
OUTPUT Deleted.BusinessEntityID,
    Deleted.VacationHours AS BeforeValue,
    Inserted.VacationHours AS AfterValue
WHERE SalariedFlag = 0;
GO

E. Use CASE v příkazu SET

Následující příklad používá CASE výraz v SET příkazu ve funkci dbo.GetContactInfotable-valued . AdventureWorks2025 V databázi jsou všechna data související s lidmi uložená v Person.Person tabulce. Osoba může být například zaměstnancem, zástupcem dodavatele nebo zákazníkem. Funkce vrátí jméno (FirstName) a rodinné jméno (LastName) daného BusinessEntityID člověka a typ kontaktu pro danou osobu. Výraz CASE v SET příkazu určuje hodnotu, která se má pro sloupec ContactType zobrazit na základě existence BusinessEntityID sloupce v objektu Employee, Vendornebo Customer tabulek.

USE AdventureWorks2022;
GO

CREATE FUNCTION dbo.GetContactInformation (
    @BusinessEntityID INT
)
RETURNS
    @retContactInformation TABLE (
        BusinessEntityID INT NOT NULL,
        FirstName NVARCHAR (50) NULL,
        LastName NVARCHAR (50) NULL,
        ContactType NVARCHAR (50) NULL,
        PRIMARY KEY CLUSTERED (BusinessEntityID ASC))
AS
-- Returns the first name, last name and contact type for the specified contact.
BEGIN
    DECLARE @FirstName NVARCHAR(50),
        @LastName NVARCHAR(50),
        @ContactType NVARCHAR(50);

    -- Get common contact information
    SELECT @BusinessEntityID = BusinessEntityID,
        @FirstName = FirstName,
        @LastName = LastName
    FROM Person.Person
    WHERE BusinessEntityID = @BusinessEntityID;

    SET @ContactType = CASE
            -- Check for employee
            WHEN EXISTS (
                    SELECT *
                    FROM HumanResources.Employee AS e
                    WHERE e.BusinessEntityID = @BusinessEntityID
                    )
                THEN 'Employee'
            -- Check for vendor
            WHEN EXISTS (
                    SELECT *
                    FROM Person.BusinessEntityContact AS bec
                    WHERE bec.BusinessEntityID = @BusinessEntityID
                    )
                THEN 'Vendor'
            -- Check for store
            WHEN EXISTS (
                    SELECT *
                    FROM Purchasing.Vendor AS v
                    WHERE v.BusinessEntityID = @BusinessEntityID
                    )
                THEN 'Store Contact'
            -- Check for individual consumer
            WHEN EXISTS (
                    SELECT *
                    FROM Sales.Customer AS c
                    WHERE c.PersonID = @BusinessEntityID
                    )
                THEN 'Consumer'
            END;

    -- Return the information to the caller
    IF @BusinessEntityID IS NOT NULL
        BEGIN
            INSERT @retContactInformation
            SELECT @BusinessEntityID,
                   @FirstName,
                   @LastName,
                   @ContactType;
        END
    RETURN;
END
GO

SELECT BusinessEntityID,
    FirstName,
    LastName,
    ContactType
FROM dbo.GetContactInformation(2200);
GO

SELECT BusinessEntityID,
    FirstName,
    LastName,
    ContactType
FROM dbo.GetContactInformation(5);
GO

F. Use CASE v klauzuli HAVING

Následující příklad používá CASE výraz v HAVING klauzuli k omezení řádků vrácených příkazem SELECT . Příkaz vrátí hodinovou sazbu pro každý název úlohy v HumanResources.Employee tabulce. Klauzule HAVING omezuje tituly na ty, které jsou drženy zaměstnanci s maximální mzdovou sazbou vyšší než 40 dolarů, nebo nealaried zaměstnanci s maximální mzdovou sazbou vyšší než 15 dolarů.

USE AdventureWorks2022;
GO

SELECT JobTitle,
    MAX(ph1.Rate) AS MaximumRate
FROM HumanResources.Employee AS e
INNER JOIN HumanResources.EmployeePayHistory AS ph1
    ON e.BusinessEntityID = ph1.BusinessEntityID
GROUP BY JobTitle
HAVING (
    MAX(CASE
            WHEN SalariedFlag = 1 THEN ph1.Rate
            ELSE NULL
        END) > 40.00
    OR MAX(CASE
            WHEN SalariedFlag = 0 THEN ph1.Rate
            ELSE NULL
        END) > 15.00
)
ORDER BY MaximumRate DESC;
GO

G. Použití vnořeného výrazu CASE ke kategorizaci výsledků

Následující příklad používá vnořený CASE výraz k kategorizaci produktů na ListPricezákladě . Pokud cena seznamu produktů překročí 1 000 dolarů, považuje se za High-endto . Zbývající produkty jsou kategorizovány ve vnořeném CASE výrazu na ProductLine základě a ListPrice.

USE AdventureWorks2022;
GO

SELECT 
    ProductNumber,
    Name,
    ListPrice,
    PriceCategory = 
        CASE 
            WHEN ListPrice > 1000 THEN 'High-end'
            ELSE 
                CASE ProductLine
                    WHEN 'R' THEN
                        CASE 
                            WHEN ListPrice > 500 THEN 'Premium Road'
                            ELSE 'Standard Road'
                        END
                    WHEN 'M' THEN
                        CASE 
                            WHEN ListPrice > 500 THEN 'Premium Mountain'
                            ELSE 'Standard Mountain'
                        END
                    WHEN 'T' THEN 'Touring'
                    ELSE 'Other'
                END
        END
FROM Production.Product
ORDER BY ListPrice DESC;

Příklady: Azure Synapse Analytics a Analytický platformový systém (PDW)

H. Použití příkazu SELECT s výrazem CASE

SELECT Výraz v rámci příkazu CASE umožňuje nahradit hodnoty v sadě výsledků na základě porovnávacích hodnot. Následující příklad používá CASE výraz ke změně zobrazení kategorií produktové řady, aby byly srozumitelnější. Pokud hodnota neexistuje, zobrazí se text Not for sale .

SELECT ProductAlternateKey,
    Category = CASE ProductLine
        WHEN 'R' THEN 'Road'
        WHEN 'M' THEN 'Mountain'
        WHEN 'T' THEN 'Touring'
        WHEN 'S' THEN 'Other sale items'
        ELSE 'Not for sale'
        END,
    EnglishProductName
FROM dbo.DimProduct
ORDER BY ProductKey;
GO

I. Použijte CASE v příkazu UPDATE

Následující příklad používá CASE výraz v UPDATE příkazu k určení hodnoty, která je nastavena pro sloupec VacationHours pro zaměstnance s SalariedFlag nastavenou hodnotou 0. Při odečítání 10 hodin od VacationHours výsledků záporné hodnoty VacationHours se zvýší o 40 hodin; jinak VacationHours se zvýší o 20 hodin.

UPDATE dbo.DimEmployee
SET VacationHours = (
        CASE
            WHEN ((VacationHours - 10.00) < 0) THEN VacationHours + 40
            ELSE (VacationHours + 20.00)
            END
        )
WHERE SalariedFlag = 0;
GO