Dela via


CASE (Transact-SQL)

Gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalysplattformssystem (PDW)SQL-analysslutpunkt i Microsoft FabricLager i Microsoft FabricSQL-databas i Förhandsversion av Microsoft Fabric

Utvärderar en lista över villkor och returnerar ett av flera möjliga resultatuttryck.

Uttrycket CASE har två format:

  • Det enklaCASE uttrycket jämför ett uttryck med en uppsättning enkla uttryck för att fastställa resultatet.

  • Det söktaCASE uttrycket utvärderar en uppsättning booleska uttryck för att fastställa resultatet.

Båda formaten stöder ett valfritt ELSE argument.

CASE kan användas i valfri instruktion eller sats som tillåter ett giltigt uttryck. Du kan till exempel använda CASE i -instruktioner som SELECT, UPDATEDELETE och SEToch i -satser som <select_list>, IN, WHERE, ORDER BYoch HAVING.

Transact-SQL syntaxkonventioner

Syntax

Syntax för SQL Server, Azure SQL Database och 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

Syntax för Parallel Data Warehouse.

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

Arguments

input_expression

Uttrycket utvärderas när det enkla CASE formatet används. input_expression är ett giltigt uttryck.

NÄR when_expression

Ett enkelt uttryck som input_expression jämförs med när det enkla CASE formatet används. when_expression är ett giltigt uttryck. Datatyperna för input_expression och varje when_expression måste vara desamma eller vara en implicit konvertering.

SEDAN result_expression

Uttrycket som returneras när input_expression är lika med when_expression utvärderas till TRUE, eller Boolean_expression utvärderas till TRUE. resultatuttryck är ett giltigt uttryck.

ELSE else_result_expression

Uttrycket returnerades om ingen jämförelseåtgärd utvärderas till TRUE. Om det här argumentet utelämnas och ingen jämförelseåtgärd utvärderas till TRUEreturnerar CASE .NULL else_result_expression är ett giltigt uttryck. Datatyperna för else_result_expression och alla result_expression måste vara desamma eller vara en implicit konvertering.

NÄR Boolean_expression

Det booleska uttrycket utvärderas när det sökta CASE formatet används. Boolean_expression är ett giltigt booleskt uttryck.

Returtyper

Returnerar den högsta prioritetstypen från uppsättningen med typer i result_expressions och den valfria else_result_expression. Mer information finns i Datatypspriorence.

Returnera värden

Enkelt CASE-uttryck

Det enkla CASE uttrycket fungerar genom att jämföra det första uttrycket med uttrycket i varje WHEN sats för likvärdighet. Om dessa uttryck är likvärdiga returneras uttrycket i THEN -satsen.

  • Tillåter endast en likhetskontroll.

  • I den angivna ordningen utvärderas input_expression = when_expression för varje sats WHEN .

  • Returnerar result_expression för den första input_expression = when_expression som utvärderas till TRUE.

  • Om ingen input_expression = when_expression utvärderas till TRUEreturnerar SQL Server Database Engine else_result_expression om en ELSE sats anges eller ett NULL värde om ingen ELSE sats har angetts.

Sökt CASE-uttryck

  • Utvärderar, i den angivna ordningen, Boolean_expression för varje sats WHEN .

  • Returnerar result_expression av den första Boolean_expression som utvärderas till TRUE.

  • Om ingen Boolean_expression utvärderas till TRUEreturnerar databasmotorn else_result_expression om en ELSE sats anges eller ett NULL värde om ingen ELSE sats anges.

Remarks

SQL Server tillåter endast 10 kapslingsnivåer i CASE uttryck.

Uttrycket CASE kan inte användas för att styra körningsflödet för Transact-SQL-instruktioner, instruktionsblock, användardefinierade funktioner och lagrade procedurer. En lista över metoder för flödeskontroll finns i Kontroll av flöde.

Uttrycket CASE utvärderar dess villkor sekventiellt och slutar med det första villkoret vars villkor är uppfyllt. I vissa situationer utvärderas ett uttryck innan ett CASE uttryck tar emot resultatet av uttrycket som indata. Det går att utvärdera dessa uttryck. Aggregerade uttryck som visas i WHEN argument till ett CASE uttryck utvärderas först och tillhandahålls sedan till CASE uttrycket. Följande fråga genererar till exempel ett dividerat fel med noll när du skapar värdet för MAX aggregeringen. Det här steget inträffar innan uttrycket utvärderas 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

Du bör bara vara beroende av ordningen på utvärderingen av WHEN villkoren för skalära uttryck (inklusive icke-korrelerade underfrågor som returnerar skalärer), inte för aggregerade uttryck.

Du måste också se till att minst ett av uttrycken THEN i - eller-satserna ELSE inte är konstanten NULL . Även om NULL kan returneras från flera resultatuttryck kan inte alla uttryckligen vara konstanten NULL . Om alla resultatuttryck använder konstanten NULL returneras fel 8133.

Examples

Kodexemplen i den här artikeln använder AdventureWorks2022- eller AdventureWorksDW2022-exempeldatabasen, som du kan ladda ned från startsidan Microsoft SQL Server Samples och Community Projects.

A. Använda en SELECT-instruktion med ett enkelt CASE-uttryck

I en SELECT -instruktion tillåter ett enkelt CASE uttryck endast en likhetskontroll. Inga andra jämförelser görs. I följande exempel används CASE uttrycket för att ändra visningen av produktradskategorier för att göra dem mer begripliga.

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. Använda en SELECT-instruktion med ett sökt CASE-uttryck

I en SELECT -instruktion tillåter det sökta CASE uttrycket att värden ersätts i resultatuppsättningen baserat på jämförelsevärden. I följande exempel visas listpriset som en textkommentare baserat på prisintervallet för en produkt.

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. Använda CASE i en ORDER BY-sats

I följande exempel används CASE uttrycket i en ORDER BY sats för att fastställa sorteringsordningen för raderna baserat på ett visst kolumnvärde. I det första exemplet utvärderas värdet i SalariedFlag kolumnen i HumanResources.Employee tabellen. Anställda som har SalariedFlag värdet 1 returneras i ordning i fallande BusinessEntityID ordning. Anställda som har SalariedFlag värdet 0 returneras i ordning i BusinessEntityID stigande ordning.

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

I det andra exemplet sorteras resultatuppsättningen efter kolumnen TerritoryName när kolumnen CountryRegionName är lika med "USA" och efter CountryRegionName för alla andra rader.

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. Använda CASE i en UPDATE-instruktion

I följande exempel används CASE uttrycket i en UPDATE -instruktion för att fastställa det värde som anges för kolumnen VacationHours för anställda med SalariedFlag värdet 0. När du subtraherar 10 timmar från VacationHours resulterar det i ett negativt värde, VacationHours ökas med 40 timmar, annars VacationHours ökas med 20 timmar. Satsen OUTPUT används för att visa värdena före och efter semester.

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. Använda CASE i en SET-instruktion

I följande exempel används CASE uttrycket i en SET -instruktion i funktionen dbo.GetContactInfotable-valued . I databasen AdventureWorks2022 lagras alla data som är relaterade till personer i Person.Person tabellen. Personen kan till exempel vara anställd, leverantörsrepresentant eller kund. Funktionen returnerar förnamnet (FirstName) och familjenamnet (LastName) för en viss BusinessEntityID och kontakttypen för den personen. Uttrycket CASE i -instruktionen SET avgör vilket värde som ska visas för kolumnen ContactType baserat på förekomsten av BusinessEntityID kolumnen i tabellerna Employee, Vendoreller Customer .

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. Använda CASE i en HAVING-sats

I följande exempel används CASE uttrycket i en HAVING -sats för att begränsa de rader som returneras av -instruktionen SELECT . Instruktionen returnerar timtaxa för varje jobbrubrik i HumanResources.Employee tabellen. Klausulen HAVING begränsar titlarna till de som innehas av tjänstemän med en maximal lönesats som är större än 40 dollar, eller icke-anställda med en maximal lönesats som är större än 15 dollar.

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. Använda ett kapslat CASE-uttryck för att kategorisera resultat

I följande exempel används ett kapslat CASE uttryck för att kategorisera produkter baserat på ListPrice. Om ett produktlistepris överstiger 1 000 dollar anses det vara High-end. De återstående produkterna kategoriseras i ett kapslat CASE uttryck baserat på ProductLine och 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;

Exempel: Azure Synapse Analytics and Analytics Platform System (PDW)

H. Använda en SELECT-instruktion med ett CASE-uttryck

I en SELECT -instruktion CASE tillåter uttrycket att värden ersätts i resultatuppsättningen baserat på jämförelsevärden. I följande exempel används CASE uttrycket för att ändra visningen av produktradskategorier för att göra dem mer begripliga. När ett värde inte finns visas texten 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. Använda CASE i en UPDATE-instruktion

I följande exempel används CASE uttrycket i en UPDATE -instruktion för att fastställa det värde som anges för kolumnen VacationHours för anställda med SalariedFlag värdet 0. När du subtraherar 10 timmar från VacationHours resulterar det i ett negativt värde, VacationHours ökas med 40 timmar, annars VacationHours ökas med 20 timmar.

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