-- 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 語法,請參閱 舊版檔 。
這是使用簡單的 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_expression 的 result_expression。
如果沒有任何 input_expression = when_expression 評估為 TRUE,若指定了 ELSE 子句,SQL Server 資料庫引擎就會傳回 else_result_expression,若未指定 ELSE 子句,則會傳回 NULL 值。
搜尋的 CASE 運算式:
依指定的順序來評估每個 WHEN 子句的 Boolean_expression。
傳回第一個評估為 TRUE 之 Boolean_expression 的 result_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
運算式會根據 Employee
、Vendor
或 Customer
資料表中的 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。
提交並檢視相關的意見反應