CASE (Transact-SQL)

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) SQL Analytics-Endpunkt in Microsoft Fabric Warehouse in Microsoft Fabric

Wertet eine Liste von Bedingungen aus und gibt einen von mehreren möglichen Ergebnisausdrücken zurück.

Der CASE-Ausdruck weist zwei Formate auf:

  • Der einfache CASE-Ausdruck vergleicht einen Ausdruck mit mehreren einfachen Ausdrücken, um das Ergebnis zu bestimmen.

  • Der komplexe CASE-Ausdruck wertet eine Menge boolescher Ausdrücke aus, um das Ergebnis zu bestimmen.

Bei beiden Formaten wird ein optionales ELSE-Argument unterstützt.

CASE kann in einer beliebigen Anweisung oder Klausel verwendet werden, die einen gültigen Ausdruck zulässt. Beispielsweise kann CASE in Anweisungen wie SELECT, UPDATE, DELETE und SET und Klauseln wie <select_list>, IN, WHERE, ORDER BY und HAVING verwendet werden.

Transact-SQL-Syntaxkonventionen

Syntax

Syntax für SQL Server, Azure SQL-Datenbank und 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

Argumente

input_expression

Der Ausdruck, der ausgewertet wird, wenn das einfache CASE-Format verwendet wird. input_expression ist ein gültiger Ausdruck.

WHEN when_expression

Ein einfacher Ausdruck, mit dem input_expression verglichen wird, wenn das einfache CASE-Format verwendet wird. when_expression ist ein gültiger Ausdruck. Die Datentypen von input_expression und allen when_expression-Ausdrücken müssen gleich sein, oder es muss eine implizite Konvertierung vorliegen.

THEN result_expression

Der Ausdruck, der zurückgegeben wird, wenn input_expression gleich when_expression mit TRUE ausgewertet oder wenn boolean_expression mit TRUE ausgewertet wird. result expression ist ein gültiger Ausdruck.

ELSE else_result_expression

Der Ausdruck, der zurückgegeben wird, wenn keine Vergleichsoperation mit TRUE ausgewertet wird. Wenn dieses Argument weggelassen wird und keine Vergleichsoperation mit TRUE ausgewertet wird, gibt die CASE-Funktion NULL zurück. else_result_expression ist ein gültiger Ausdruck. Die Datentypen von else_result_expression und allen result_expression-Ausdrücken müssen gleich sein, oder es muss eine implizite Konvertierung vorliegen.

WHEN Boolean_expression

Der boolesche Ausdruck, der ausgewertet wird, wenn das komplexe CASE-Format verwendet wird. Boolean_expression ist in gültiger boolescher Ausdruck.

Rückgabetypen

Gibt den Typ mit höchsten Priorität in result_expressions und in dem optionalen else_result_expression-Ausdruck zurück. Weitere Informationen finden Sie unter Rangfolge der Datentypen (Transact-SQL).

Rückgabewerte

Einfacher CASE-Ausdruck:

Beim einfachen CASE-Ausdruck wird verglichen, ob der erste Ausdruck mit dem Ausdruck in den einzelnen WHEN-Klauseln gleichwertig ist. Wenn diese Ausdrücke gleichwertig sind, wird der Ausdruck in der THEN-Klausel zurückgegeben.

  • Lässt nur eine Gleichheitsüberprüfung zu.

  • Wertet input_expression = when_expression in der angegebenen Reihenfolge für jede WHEN-Klausel aus.

  • Gibt für die erste input_expression = when_expression, die TRUE ergibt, result_expression zurück.

  • Wird kein input_expression = when_expression-Ausdruck TRUE ergibt, gibt SQL Server-Datenbank-Engine den else_result_expression-Ausdruck zurück, falls eine ELSE-Klausel angegeben ist, oder einen NULL-Wert, falls keine ELSE-Klausel angegeben ist.

Komplexe CASE-Ausdrücke:

  • Für jede WHEN-Klausel werden die Boolean_expression-Ausdrücke in der angegebenen Reihenfolge ausgewertet.

  • Gibt den result_expression-Ausdruck des ersten Boolean_expression-Ausdruck zurück, der TRUE ergibt.

  • Wird kein Boolean_expression-Ausdruck zu TRUE ausgewertet, gibt Datenbank-Engine den else_result_expression-Ausdruck zurück, falls eine ELSE-Klausel angegeben ist, oder einen NULL-Wert, falls keine ELSE-Klausel angegeben ist.

Bemerkungen

In SQL Server ist für CASE-Ausdrücke nur eine Schachtelung von 10 Ebenen zulässig.

Der CASE-Ausdruck kann nicht verwendet werden, um den Ablauf bei der Ausführung von Transact-SQL-Anweisungen, Anweisungsblöcken, benutzerdefinierten Funktionen und gespeicherten Prozeduren zu steuern. Eine Liste der Methoden zur Ablaufsteuerung finden Sie unter Sprachkonstrukte zur Ablaufsteuerung (Transact-SQL).

Der CASE-Ausdruck bewertet ihre Bedingungen sequenziell und hält bei der ersten Bedingung an, deren Bedingung erfüllt ist. In einigen Situationen wird ein Ausdruck bewertet, bevor ein CASE-Ausdruck die Ergebnisse des Ausdrucks als Eingabe empfängt. Bei der Bewertung dieser Ausdrücke sind Fehler möglich. Aggregierte Ausdrücke, die in WHEN-Argumenten für einen CASE-Ausdruck angezeigt werden, werden zuerst ausgewertet und dann dem CASE-Ausdruck bereitgestellt. Beim Erzeugen des MAX-Aggregat-Werts erzeugt die folgende Abfrage beispielsweise einen Fehler aufgrund einer Division durch Null. Dies erfolgt vor dem Auswerten des CASE-Ausdrucks.

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

Sie sollten nur von der Reihenfolge der Bewertung der WHEN-Bedingungen für skalare Ausdrücke abhängig sein (einschließlich nicht korrelierter Unterabfragen, die Skalare zurückgeben), nicht für aggregierte Ausdrücke.

Sie müssen auch sicherstellen, dass mindestens einer der Ausdrücke in den THEN- oder ELSE-Klauseln nicht die NULL-Konstante ist. Zwar kann NULL von mehreren Ergebnisausdrücken zurückgegeben werden, aber nicht alle davon können explizit die NULL-Konstante sein. Wenn alle Ergebnisausdrücke die NULL-Konstante verwenden, wird der Fehler 8133 zurückgegeben.

Beispiele

A. Verwenden einer SELECT-Anweisung mit einem einfachen CASE-Ausdruck

Innerhalb einer SELECT-Anweisung ermöglicht ein einfacher CASE-Ausdruck nur eine Überprüfung auf Gleichheit. Andere Vergleiche werden nicht angestellt. Im folgenden Beispiel wird ein CASE-Ausdruck verwendet, um die Anzeige von Produktkategorien so zu ändern, dass sie leichter verständlich werden.

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. Verwenden einer SELECT-Anweisung mit einem komplexen CASE-Ausdruck

Innerhalb einer SELECT-Anweisung können mit dem komplexen CASE-Ausdruck Werte im Resultset basierend auf den Vergleichsergebnissen ersetzt werden. Im folgenden Beispiel wird anstelle des Listenpreises ein Kommentar angezeigt, der vom Preisbereich der einzelnen Produkte abhängt.

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. Verwenden von CASE in einer ORDER BY-Klausel

In den folgenden Beispielen wird der CASE-Ausdruck in einer ORDER BY-Klausel verwendet, um die Sortierreihenfolge der Zeilen auf Grundlage eines angegebenen Spaltenwerts zu bestimmen. Im ersten Beispiel wird der Wert in der SalariedFlag-Spalte der HumanResources.Employee-Tabelle ausgewertet. Mitarbeiter, deren SalariedFlag auf 1 festgelegt wurde, werden nach BusinessEntityID in absteigender Folge zurückgegeben. Mitarbeiter, deren SalariedFlag auf 0 festgelegt wurde, werden nach BusinessEntityID in aufsteigender Folge zurückgegeben. Im zweiten Beispiel wird das Resultset nach der TerritoryName-Spalte sortiert, wenn die CountryRegionName-Spalte gleich 'United States' ist, und bei allen anderen Zeilen nach CountryRegionName.

SELECT BusinessEntityID,
    SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag
        WHEN 1 THEN BusinessEntityID
        END DESC,
    CASE
        WHEN SalariedFlag = 0 THEN BusinessEntityID
        END;
GO
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: Verwenden von CASE in einer UPDATE-Anweisung

Im folgenden Beispiel wird der CASE-Ausdruck in einer UPDATE-Anweisung verwendet, um den Wert zu bestimmen, der für die Spalte VacationHoursfür Mitarbeiter mit SalariedFlag gleich 0 festgelegt wurde. Wenn von VacationHours 10 Stunden subtrahiert werden, und dies einen negativen Wert ergibt, wird VacationHours um 40 Stunden erhöht; andernfalls wird VacationHours um 20 Stunden erhöht. Die OUTPUT-Klausel wird verwendet, um die Werte vor und nach dem Urlaub anzuzeigen.

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. Verwenden von CASE in einer SET-Anweisung

Im folgenden Beispiel wird der CASE-Ausdruck in einer SET-Anweisung in der Tabellenwertfunktion dbo.GetContactInfo verwendet. In der AdventureWorks2022-Datenbank werden alle Daten zu Personen in der Person.Person-Tabelle gespeichert. Die Person kann z.B. ein Mitarbeiter, Herstellerkontakt oder Kunde sein. Die Funktion gibt den Vor- und Nachnamen einer angegebenen BusinessEntityID und den Kontakttyp für diese Person zurück. Der CASE-Ausdruck in der SET-Anweisung bestimmt den Wert, der für die Spalte ContactType basierend auf dem Vorhandensein der Spalte BusinessEntityID in der Tabelle Employee, Vendor oder Customer angezeigt werden soll.

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. Verwenden von CASE in einer HAVING-Klausel

Im folgenden Beispiel wird der CASE-Ausdruck in einer HAVING-Klausel verwendet, um die von der SELECT-Anweisung zurückgegebenen Zeilen einzuschränken. Die Anweisung gibt den maximalen Stundensatz für jede Berufsbezeichnung in der Tabelle HumanResources.Employee zurück. Die HAVING-Klausel schränkt die Bezeichnungen auf die Posten ein, die von Angestellten mit einem maximalen Stundenlohn von mehr als 40 USD oder von Nichtangestellten mit einem maximalen Stundenlohn von mehr als 15 USD besetzt sind.

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

Beispiele: Azure Synapse Analytics und Analytics-Plattformsystem (PDW)

G. Verwenden einer SELECT-Anweisung mit einem CASE-Ausdruck

Innerhalb einer SELECT-Anweisung können mit dem komplexen CASE-Ausdruck Werte im Resultset basierend auf den Vergleichsergebnissen ersetzt werden. Im folgenden Beispiel wird ein CASE-Ausdruck verwendet, um die Anzeige von Produktkategorien so zu ändern, dass sie leichter verständlich werden. Wenn ein Wert nicht vorhanden ist, wird der Text „Not for sale“ (Nicht zu verkaufen) angezeigt.

-- Uses AdventureWorks

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

H. Verwenden von CASE in einer UPDATE-Anweisung

Im folgenden Beispiel wird der CASE-Ausdruck in einer UPDATE-Anweisung verwendet, um den Wert zu bestimmen, der für die Spalte VacationHoursfür Mitarbeiter mit SalariedFlag gleich 0 festgelegt wurde. Wenn von VacationHours 10 Stunden subtrahiert werden, und dies einen negativen Wert ergibt, wird VacationHours um 40 Stunden erhöht; andernfalls wird VacationHours um 20 Stunden erhöht.

-- Uses AdventureWorks

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

Weitere Informationen