適用于: Microsoft Fabric 中 Microsoft Fabric 倉儲中的 SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW) SQL 分析端點

評估一份條件清單,並傳回多個可能的結果運算式之一。

CASE 運算式有兩種格式:

  • 簡單的 CASE 運算式會比較運算式和一組簡單運算式來得出結果。

  • 搜尋的 CASE 運算式會評估一組布林運算式來得出結果。

    兩種格式都支援選用的 ELSE 引數。

    CASE 可以用在允許有效運算式的任何陳述式或子句中。 例如,您可以在 SELECT、UPDATE、DELETE 和 SET 之類的陳述式,以及 <select_list> 、IN、WHERE、ORDER BY 和 HAVING 之類的子句中使用 CASE

    Transact-SQL 語法慣例

    Syntax

    SQL Server、Azure SQL Database 和 Azure Synapse Analytics 的語法。

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

    平行處理資料倉儲的語法。

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

    若要檢視 SQL Server 2014 (12.x) 和舊版的 Transact-SQL 語法,請參閱 舊版檔

    input_expression

    這是使用簡單的 CASE 格式時,所評估的運算式。 input_expression 是任何有效的運算式

    WHEN when_expression

    這是使用簡單的 CASE 格式時,要與 input_expression 進行比較的簡單運算式。 when_expression 是任何有效的運算式。 input_expression 和每個 when_expression 的資料類型都必須相同,或必須能夠進行隱含轉換。

    THEN result_expression

    這是當 input_expression 等於 when_expression 評估為 TRUE 或 Boolean_expression 評估為 TRUE 時,所傳回的運算式。 result expression 是任何有效的運算式

    ELSE else_result_expression

    這是沒有任何比較運算評估為 TRUE 時,所傳回的運算式。 如果省略這個引數,且沒有任何比較運算評估為 TRUE,CASE 就會傳回 NULL。 else_result_expression 是任何有效的運算式。 else_result_expression 和任何 result_expression 的資料類型都必須相同,或必須能夠進行隱含轉換。

    WHEN Boolean_expression

    這是使用搜尋的 CASE 格式時,所評估的布林運算式。 Boolean_expression 是任何有效的布林值運算式。

    若要檢視 SQL Server 2014 (12.x) 和舊版的 Transact-SQL 語法,請參閱 舊版檔

    result_expressions 和選擇性 else_result_expression 的類型集傳回優先順序最高的類型。 如需詳細資訊,請參閱資料類型優先順序 (Transact-SQL)

    簡單的 CASE 運算式:

    簡單的 CASE 運算式會透過比較第一個運算式與每個 WHEN 子句中的運算式是否相等來運算。 如果這些運算式相等,將會傳回 THEN 子句中的運算式。

  • 僅允許相等檢查。

  • 依指定的順序來評估每個 WHEN 子句的 input_expression = when_expression。

  • 傳回第一個評估為 TRUE 之 input_expression = when_expressionresult_expression

  • 如果沒有任何 input_expression = when_expression 評估為 TRUE,若指定了 ELSE 子句,SQL Server 資料庫引擎就會傳回 else_result_expression,若未指定 ELSE 子句,則會傳回 NULL 值。

    搜尋的 CASE 運算式:

  • 依指定的順序來評估每個 WHEN 子句的 Boolean_expression

  • 傳回第一個評估為 TRUE 之 Boolean_expressionresult_expression

  • 如果沒有任何 Boolean_expression 評估為 TRUE,若指定了 ELSE 子句,資料庫引擎就會傳回 else_result_expression,若未指定 ELSE 子句,則會傳回 NULL 值。

    SQL Server 在 CASE 運算式中只允許 10 層的巢狀層級。

    CASE 運算式無法用於控制 Transact-SQL 陳述式、陳述式區塊、使用者定義函數及預存程序的執行流程。 如需流程控制方法的清單,請參閱流程控制語言 (Transact-SQL)

    CASE 運算式會依序評估其條件,並在滿足其條件的第一個條件時停止。 在某些情況下,運算式會先進行評估,CASE 運算式才會收到該運算式的結果作為其輸入。 評估這些運算式是否可能時發生錯誤。 出現在 CASE 運算式之 WHEN 引數中的彙總運算式會先進行評估,再提供給 CASE 運算式。 例如,下列查詢會在產生 MAX 彙總的值時,產生除以零的錯誤。 這個情況會在評估 CASE 運算式之前發生。

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

    針對純量運算式 (包括傳回純量的非相互關聯子查詢,而非針對彙總運算式),您應該僅相依於 WHEN 條件的評估順序。

    您也必須確定 THEN 或 ELSE 子句中至少有一個運算式不是 NULL 常數。 雖然可能會從多個結果運算式傳回 NULL,但並非所有結果運算式都可以明確作為 NULL 常數。 如果所有結果運算式都使用 NULL 常數,則會傳回錯誤 8133。

    A. 使用 SELECT 陳述式搭配簡單的 CASE 運算式

    SELECT 陳述式內,只允許相等檢查使用簡單的 CASE 運算式,不能進行任何其他比較。 下列範例利用 CASE 運算式來變更產品線類別目錄的顯示方式,使它們更容易了解。

    USE AdventureWorks2022;
    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'
    FROM Production.Product
    ORDER BY ProductNumber;
    

    B. 使用 SELECT 陳述式搭配搜尋的 CASE 運算式

    SELECT 陳述式內,搜尋的 CASE 運算式允許以比較值為基礎來取代結果集中的值。 下列範例以產品的價格範圍為基礎,將標價顯示為文字註解。

    USE AdventureWorks2022;
    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'
    FROM Production.Product
    ORDER BY ProductNumber;
    

    C. 在 ORDER BY 子句中使用 CASE

    下列範例在 ORDER BY 子句中使用 CASE 運算式,根據指定的資料行值,決定資料列的排序次序。 在第一則範例中,系統會評估 SalariedFlag 資料表之 HumanResources.Employee 資料行的值。 將 SalariedFlag 設定為 1 的員工會以 BusinessEntityID 的遞減順序傳回。 將 SalariedFlag 設定為 0 的員工會以 BusinessEntityID 的遞增順序傳回。 在第二則範例中,結果集會依照資料行 TerritoryName 排序 (當資料行 CountryRegionName 等於 'United States' 時) 以及依照 CountryRegionName 排序 (針對所有其他資料列)。

    SELECT BusinessEntityID,
        SalariedFlag
    FROM HumanResources.Employee
    ORDER BY CASE SalariedFlag
            WHEN 1 THEN BusinessEntityID
            END DESC,
            WHEN SalariedFlag = 0 THEN BusinessEntityID
    
    SELECT BusinessEntityID,
        LastName,
        TerritoryName,
        CountryRegionName
    FROM Sales.vSalesPerson
    WHERE TerritoryName IS NOT NULL
    ORDER BY CASE CountryRegionName
            WHEN 'United States' THEN TerritoryName
            ELSE CountryRegionName
    

    D. 在 UPDATE 陳述式中使用 CASE

    下列範例在 UPDATE 陳述式中使用 CASE 運算式來決定 SalariedFlag 設定為 0 時,針對員工之 VacationHours 資料行設定的值。 從 VacationHours 減去 10 小時變成負值時,VacationHours 會加上 40 小時,否則 VacationHours 會加上 20 小時。 OUTPUT 子句用於顯示假期值之前和之後。

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

    E. 在 SET 陳述式中使用 CASE

    下列範例會在資料表值函數 dbo.GetContactInfo 的 SET 陳述式中使用 CASE 運算式。 在 AdventureWorks2022 資料庫中,與人員相關的所有資料都會儲存在 Person.Person 資料表中。 例如,該人員可能是員工、廠商代表或客戶。 此函數會傳回指定 BusinessEntityID 的名字和姓氏,以及該人員的連絡人類型。 SET 陳述式中的 CASE 運算式會根據 EmployeeVendorCustomer 資料表中的 BusinessEntityID 資料行是否存在,來決定要對 ContactType 資料行顯示的值。

    USE AdventureWorks2022;
    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)
    -- 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'
        -- Return the information to the caller
        IF @BusinessEntityID IS NOT NULL
        BEGIN
            INSERT @retContactInformation
            SELECT @BusinessEntityID,
                @FirstName,
                @LastName,
                @ContactType;
        RETURN;
    SELECT BusinessEntityID,
        FirstName,
        LastName,
        ContactType
    FROM dbo.GetContactInformation(2200);
    SELECT BusinessEntityID,
        FirstName,
        LastName,
        ContactType
    FROM dbo.GetContactInformation(5);
    

    F. 在 HAVING 子句中使用 CASE

    下列範例會在 HAVING 子句中使用 CASE 運算式來限制 SELECT 陳述式所傳回的資料列。 此陳述式會傳回 HumanResources.Employee 資料表中每個職稱的時薪。 HAVING 子句會將職稱限制為薪水上限大於 40 美金之支薪員工所持有的職稱,以及薪水上限大於 15 美金之非支薪員工所持有的職稱。

    USE AdventureWorks2022;
    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;
    

    範例:Azure Synapse Analytics 和 Analytics Platform System (PDW)

    G. 使用 SELECT 陳述式搭配 CASE 運算式

    在 SELECT 陳述式內,CASE 運算式允許根據比較值來取代結果集中的值。 下列範例利用 CASE 運算式來變更產品線類別目錄的顯示方式,使它們更容易了解。 若值並不存在,即會顯示 "Not for sale' 的字樣。

    -- 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'
        EnglishProductName
    FROM dbo.DimProduct
    ORDER BY ProductKey;
    

    H. 在 UPDATE 陳述式中使用 CASE

    下列範例在 UPDATE 陳述式中使用 CASE 運算式來決定 SalariedFlag 設定為 0 時,針對員工之 VacationHours 資料行設定的值。 從 VacationHours 減去 10 小時變成負值時,VacationHours 會加上 40 小時,否則 VacationHours 會加上 20 小時。

    -- Uses AdventureWorks
    UPDATE dbo.DimEmployee
    SET VacationHours = (
                WHEN ((VacationHours - 10.00) < 0) THEN VacationHours + 40
                ELSE (VacationHours + 20.00)
    WHERE SalariedFlag = 0;
    
  • 運算式 (Transact-SQL)
  • SELECT (Transact-SQL)
  • COALESCE (Transact-SQL)
  • IIF (Transact-SQL)
  • CHOOSE (Transact-SQL)
  • 即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:https://aka.ms/ContentUserFeedback

    提交並檢視相關的意見反應

  •