Delen via


CASE (Transact-SQL)

Van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)SQL Analytics-eindpunt in Microsoft FabricMagazijn in Microsoft FabricSQL-database in Microsoft Fabric Preview

Evalueert een lijst met voorwaarden en retourneert een van meerdere mogelijke resultaatexpressies.

De CASE expressie heeft twee indelingen:

  • Met de eenvoudigeCASE expressie wordt een expressie vergeleken met een set eenvoudige expressies om het resultaat te bepalen.

  • De gezochteCASE expressie evalueert een set Boole-expressies om het resultaat te bepalen.

Beide indelingen ondersteunen een optioneel ELSE argument.

CASE kan worden gebruikt in elke instructie of component die een geldige expressie toestaat. U kunt bijvoorbeeld gebruiken CASE in instructies zoals SELECT, UPDATEDELETE en , en SETin componenten zoals <select_list>, IN, , WHERE, , ORDER BYen .HAVING

Transact-SQL syntaxis-conventies

Syntax

Syntaxis voor SQL Server, Azure SQL Database en 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

Syntaxis voor parallel datawarehouse.

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

Arguments

input_expression

De expressie die wordt geëvalueerd wanneer de eenvoudige CASE indeling wordt gebruikt. input_expression is een geldige expressie.

WANNEER when_expression

Een eenvoudige expressie waarmee input_expression wordt vergeleken wanneer de eenvoudige CASE indeling wordt gebruikt. when_expression een geldige expressie is. De gegevenstypen van input_expression en elke when_expression moeten hetzelfde zijn of een impliciete conversie zijn.

RESULT_EXPRESSION

De expressie die wordt geretourneerd wanneer input_expression gelijk is aan when_expression resulteert in TRUE, of Boolean_expression resulteert in TRUE. resultaatexpressie is een geldige expressie.

ELSE else_result_expression

De expressie die wordt geretourneerd als er geen vergelijkingsbewerking wordt TRUEgeëvalueerd. Als dit argument wordt weggelaten en er geen vergelijkingsbewerking wordt TRUEgeëvalueerd, CASE wordt geretourneerd NULL. else_result_expression een geldige expressie is. De gegevenstypen van else_result_expression en eventuele result_expression moeten hetzelfde zijn of een impliciete conversie zijn.

WANNEER Boolean_expression

De Boole-expressie die wordt geëvalueerd bij gebruik van de gezochte CASE indeling. Boolean_expression een geldige Booleaanse expressie is.

Retourtypen

Retourneert het hoogste prioriteitstype uit de set typen in result_expressions en de optionele else_result_expression. Zie Prioriteit van gegevenstypevoor meer informatie.

Retourwaarden

Eenvoudige CASE-expressie

De eenvoudige CASE expressie werkt door de eerste expressie te vergelijken met de expressie in elke WHEN component voor gelijkwaardigheid. Als deze expressies gelijkwaardig zijn, wordt de expressie in de THEN component geretourneerd.

  • Staat alleen een gelijkheidscontrole toe.

  • Evalueert in de opgegeven volgorde input_expression = when_expression voor elke WHEN component.

  • Retourneert de result_expression van de eerste input_expression = when_expression die resulteert in TRUE.

  • Als er geen input_expression = when_expression geëvalueerd, retourneert TRUEde SQL Server Database Engine de else_result_expression als er een ELSE component is opgegeven of een NULL waarde als er geen ELSE component is opgegeven.

Gezochte CASE-expressie

  • Evalueert, in de opgegeven volgorde, Boolean_expression voor elke WHEN component.

  • Retourneert result_expression van de eerste Boolean_expression die resulteert in TRUE.

  • Als er geen Boolean_expression geëvalueerd, retourneert TRUEde database-engine de else_result_expression als er een ELSE component is opgegeven of een NULL waarde als er geen ELSE component is opgegeven.

Remarks

MET SQL Server kunt u slechts 10 niveaus nesten in CASE expressies.

De CASE expressie kan niet worden gebruikt om de uitvoeringsstroom van Transact-SQL instructies, instructieblokken, door de gebruiker gedefinieerde functies en opgeslagen procedures te beheren. Zie Control-of-Flow voor een lijst met besturings-of-stroommethoden.

De CASE expressie evalueert de voorwaarden sequentieel en stopt met de eerste voorwaarde waarvan aan de voorwaarde is voldaan. In sommige situaties wordt een expressie geëvalueerd voordat een CASE expressie de resultaten van de expressie ontvangt als invoer. Fouten bij het evalueren van deze expressies zijn mogelijk. Geaggregeerde expressies die in WHEN argumenten voor een CASE expressie worden weergegeven, worden eerst geëvalueerd en vervolgens aan de CASE expressie geleverd. De volgende query produceert bijvoorbeeld een verdeling door nul bij het produceren van de waarde van de MAX statistische waarde. Deze stap vindt plaats voordat u de CASE expressie evalueert.

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

U moet alleen afhankelijk zijn van de volgorde van evaluatie van de WHEN voorwaarden voor scalaire expressies (inclusief niet-gerelateerde subquery's die scalaire waarden retourneren), niet voor statistische expressies.

U moet er ook voor zorgen dat ten minste één van de expressies in de THEN of ELSE componenten niet de NULL constante is. Hoewel NULL deze kunnen worden geretourneerd vanuit meerdere resultaatexpressies, kunnen niet alle expressies expliciet de NULL constante zijn. Als alle resultaatexpressies de NULL constante gebruiken, wordt fout 8133 geretourneerd.

Examples

De codevoorbeelden in dit artikel gebruiken de AdventureWorks2022 of AdventureWorksDW2022 voorbeelddatabase die u kunt downloaden van de startpagina van Microsoft SQL Server Samples en Community Projects .

A. Een SELECT-instructie gebruiken met een eenvoudige CASE-expressie

Binnen een SELECT instructie maakt een eenvoudige CASE expressie alleen een gelijkheidscontrole mogelijk; er worden geen andere vergelijkingen gemaakt. In het volgende voorbeeld wordt de CASE expressie gebruikt om de weergave van productregelcategorieën te wijzigen om ze begrijpelijker te maken.

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. Een SELECT-instructie gebruiken met een doorzochte CASE-expressie

In een SELECT instructie kunt u met de gezochte CASE expressie waarden vervangen in de resultatenset op basis van vergelijkingswaarden. In het volgende voorbeeld wordt de catalogusprijs weergegeven als een tekstopmerking op basis van het prijsbereik voor een product.

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 in een ORDER BY-component

In de volgende voorbeelden wordt de CASE expressie in een ORDER BY component gebruikt om de sorteervolgorde van de rijen te bepalen op basis van een bepaalde kolomwaarde. In het eerste voorbeeld wordt de waarde in de SalariedFlag kolom van de HumanResources.Employee tabel geëvalueerd. Werknemers die de SalariedFlag set hebben ingesteld op 1, worden op volgorde geretourneerd door de BusinessEntityID in aflopende volgorde. Werknemers met de SalariedFlag waarde 0 worden in oplopende BusinessEntityID volgorde geretourneerd.

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

In het tweede voorbeeld wordt de resultatenset gerangschikt op de kolom TerritoryName wanneer de kolom CountryRegionName gelijk is aan 'Verenigde Staten' en CountryRegionName op voor alle andere rijen.

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. Use CASE in een UPDATE-instructie

In het volgende voorbeeld wordt de CASE expressie in een UPDATE instructie gebruikt om de waarde te bepalen die is ingesteld voor de kolom VacationHours voor werknemers met SalariedFlag de waarde 0. Wanneer u 10 uur aftrekken van VacationHours resultaten in een negatieve waarde, VacationHours wordt dit met 40 uur verhoogd; anders VacationHours wordt dit met 20 uur verhoogd. De OUTPUT component wordt gebruikt om de waarden voor vóór en na vakantie weer te geven.

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 in een SET-instructie

In het volgende voorbeeld wordt de CASE expressie gebruikt in een SET instructie in de tabelwaardefunctie dbo.GetContactInfo. In de AdventureWorks2022 database worden alle gegevens met betrekking tot personen opgeslagen in de Person.Person tabel. De persoon kan bijvoorbeeld een werknemer, leveranciervertegenwoordiger of klant zijn. De functie retourneert de voornaam (FirstName) en de familienaam (LastName) van een bepaalde BusinessEntityID persoon en het type contactpersoon voor die persoon. De CASE expressie in de SET instructie bepaalt de waarde die moet worden weergegeven voor de kolom ContactType op basis van het bestaan van de BusinessEntityID kolom in de Employee, Vendorof Customer tabellen.

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 in een HAVING-component

In het volgende voorbeeld wordt de CASE expressie in een HAVING component gebruikt om de rijen te beperken die door de SELECT instructie worden geretourneerd. De instructie retourneert het uurtarief voor elke functie in de HumanResources.Employee tabel. De HAVING clausule beperkt de titels tot de titels die worden gehouden door gesalarismedewerkers met een maximumloontarief dat groter is dan 40 dollar, of niet-bezoldigde werknemers met een maximumloontarief dat groter is dan 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. Een geneste CASE-expressie gebruiken om resultaten te categoriseren

In het volgende voorbeeld wordt een geneste CASE expressie gebruikt om producten te categoriseren op ListPricebasis van . Als een productlijstprijs hoger is dan 1.000 dollar, wordt deze beschouwd.High-end De resterende producten worden gecategoriseerd in een geneste CASE expressie op ProductLine basis van en 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;

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

H. Een SELECT-instructie gebruiken met een CASE-expressie

In een SELECT instructie CASE kunnen waarden in de resultatenset worden vervangen op basis van vergelijkingswaarden. In het volgende voorbeeld wordt de CASE expressie gebruikt om de weergave van productregelcategorieën te wijzigen om ze begrijpelijker te maken. Wanneer er geen waarde bestaat, wordt de tekst Not for sale weergegeven.

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. Use CASE in een UPDATE-instructie

In het volgende voorbeeld wordt de CASE expressie in een UPDATE instructie gebruikt om de waarde te bepalen die is ingesteld voor de kolom VacationHours voor werknemers met SalariedFlag de waarde 0. Wanneer u 10 uur aftrekken van VacationHours resultaten in een negatieve waarde, VacationHours wordt dit met 40 uur verhoogd; anders VacationHours wordt dit met 20 uur verhoogd.

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