CASE(Transact-SQL)

조건 목록을 평가하고 가능한 여러 결과 식 중 하나를 반환합니다.

CASE 식에는 두 가지 형식이 있습니다.

  • 단순 CASE 식은 특정 식을 일련의 단순 식과 비교하여 결과를 결정합니다.

  • 검색된 CASE 식은 일련의 부울 식을 평가하여 결과를 결정합니다.

두 가지 형식 모두 선택 사항인 ELSE 인수를 지원합니다.

CASE는 유효한 식이 허용되는 모든 문 및 절에 사용할 수 있습니다. 예를 들어 SELECT, UPDATE, DELETE 및 SET과 같은 문과 select_list, IN, WHERE, ORDER BY 및 HAVING과 같은 절에 CASE를 사용할 수 있습니다.

항목 링크 아이콘 Transact-SQL 구문 표기 규칙

구문

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

인수

  • input_expression
    단순 CASE 형식을 사용할 때 평가되는 식입니다. input_expression은 유효한 입니다.

  • WHEN when_expression
    단순 CASE 형식을 사용할 때 input_expression과 비교되는 단순 식입니다. when_expression은 유효한 식입니다. input_expression과 각 when_expression의 데이터 형식은 동일하거나 암시적으로 변환되어야 합니다.

  • THEN result_expression
    input_expression이 when_expression과 같거나 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은 유효한 부울 식입니다.

반환 형식

result_expressions와 선택 사항인 else_result_expression의 형식 집합에서 우선 순위가 가장 높은 형식을 반환합니다. 자세한 내용은 데이터 형식 우선 순위(Transact-SQL)를 참조하십시오.

반환 값

단순 CASE 식:

단순 CASE 식은 첫 번째 식이 각 WHEN 절의 식과 같은지 비교하는 방식으로 작동합니다. 이러한 식이 같으면 THEN 절의 식이 반환됩니다.

  • 동등성만 검사합니다.

  • input_expression을 평가한 다음 지정된 순서대로 각 WHEN 절에 대해 input_expression = when_expression을 평가합니다.

  • 먼저 TRUE로 평가된 input_expression = when_expression의 result_expression을 반환합니다.

  • TRUE로 평가된 input_expression = when_expression이 없으면 ELSE 절이 지정된 경우 SQL Server 데이터베이스 엔진에서 else_result_expression을 반환하고 ELSE 절이 지정되지 않은 경우 NULL 값을 반환합니다.

검색된 CASE 식:

  • 지정된 순서대로 각 WHEN 절에 대해 Boolean_expression을 평가합니다.

  • 먼저 TRUE로 평가된 Boolean_expression의 result_expression을 반환합니다.

  • TRUE로 평가된 Boolean_expression이 없으면 ELSE 절이 지정된 경우 데이터베이스 엔진에서 else_result_expression을 반환하고 ELSE 절이 지정되지 않은 경우 NULL 값을 반환합니다.

주의

SQL Server에서는 CASE 식의 중첩을 10개 수준까지만 허용합니다.

Transact-SQL 문, 문 블록, 사용자 정의 함수 및 저장 프로시저의 실행 흐름을 제어하는 데 CASE 식을 사용할 수는 없습니다. 흐름 제어 메서드의 목록을 보려면 흐름 제어 언어(Transact-SQL)를 참조하십시오.

CASE 문은 해당 조건을 순서대로 평가하고 충족되는 첫 번째 조건에서 중지합니다. CASE 문이 식 결과를 입력으로 받기 전에 식이 계산되는 경우도 있습니다. 이러한 식을 계산하는 동안 오류가 발생할 수 있습니다. CASE 문의 WHEN 인수에 나타나는 집계 식이 먼저 계산된 다음 CASE 문에 제공됩니다. 예를 들어, 다음 쿼리는 MAX 집계 값을 생성할 때 0으로 나누기 오류를 생성합니다. 이는 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 ;

집계 식이 아닌 스칼라 식(스칼라를 반환하는 상호 관련되지 않은 하위 쿼리)의 경우 WHEN 조건의 평가 순서만 사용해야 합니다.

1.SELECT 문에 단순 CASE 식 사용

SELECT 문 내에서 단순 CASE 식은 동등성만 검사하고 다른 비교 작업은 수행할 수 없습니다. 다음 예에서는 CASE 식을 사용하여 제품 라인 범주 표시를 이해하기 쉽게 변경합니다.

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

2.SELECT 문에 검색된 CASE 식 사용

SELECT 문 내에서 검색된 CASE 식은 비교 값에 따라 결과 집합의 값이 바뀌도록 합니다. 다음 예에서는 제품의 가격 범위에 따라 가격을 텍스트 설명으로 표시합니다.

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

3.ORDER BY 절에 CASE 사용

다음 예에서는 ORDER BY 절에 CASE 식을 사용하여 지정된 열 값에 따라 행의 정렬 순서를 결정합니다. 첫 번째 예에서는 HumanResources.Employee 테이블의 SalariedFlag 열의 값이 계산됩니다. SalariedFlag가 1로 설정된 직원은 EmployeeID 순서에 따라 내림차순으로 반환됩니다. SalariedFlag가 0으로 설정된 직원은 EmployeeID 순서에 따라 오름차순으로 반환됩니다. 두 번째 예에서 결과 집합은 CountryRegionName 열이 'United States'와 동일하면 TerritoryName 열을 기준으로 정렬되고 그 외 다른 행에는 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;

4.UPDATE 문에 CASE 사용

다음 예에서는 UPDATE 문에 CASE 식을 사용하여 SalariedFlag가 0으로 설정된 직원의 열 VacationHours에 설정된 값을 확인합니다. VacationHours에서 10시간을 뺀 결과 음수 값이 되면 VacationHours가 40시간 증가되고, 그렇지 않으면 VacationHours가 20시간 증가됩니다. OUTPUT 절은 휴가의 이전 값과 이후 값을 표시하는 데 사용됩니다.

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

5.SET 문에 CASE 사용

다음 예에서는 테이블 반환 함수 dbo.GetContactInfo에서 SET 문에 CASE 식을 사용합니다. AdventureWorks2012 데이터베이스에서 사람과 관련된 모든 데이터는 Person.Person 테이블에 저장됩니다. 예를 들어 직원, 공급업체 담당자 또는 소비자와 같은 사람이 있을 수 있습니다. 이 함수는 지정된 BusinessEntityID의 성과 이름 및 이 사람의 연락처 유형을 반환합니다. SET 문의 CASE 식은 Employee, Vendor 또는 Customer 테이블에 BusinessEntityID 열이 있는지 여부에 따라 ContactType 열에 대해 표시할 값을 결정합니다.

   USE AdventureWorks2012;
    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);

6.HAVING 절에 CASE 사용

다음 예에서는 HAVING 절에 CASE 식을 사용하여 SELECT 문에서 반환하는 행을 제한합니다. 이 문은 HumanResources.Employee 테이블의 각 직함에 대한 최대 시간당 급여를 반환합니다. HAVING 절은 직함을 최대 급여가 40달러가 넘는 남자 직원의 직함 또는 최대 급여가 42달러가 넘는 여자 직원의 직함으로 제한합니다.

USE AdventureWorks2012;
GO
SELECT JobTitle, MAX(ph1.Rate)AS MaximumRate
FROM HumanResources.Employee AS e
JOIN HumanResources.EmployeePayHistory AS ph1 ON e.BusinessEntityID = ph1.BusinessEntityID
GROUP BY JobTitle
HAVING (MAX(CASE WHEN Gender = 'M' 
        THEN ph1.Rate 
        ELSE NULL END) > 40.00
     OR MAX(CASE WHEN Gender  = 'F' 
        THEN ph1.Rate  
        ELSE NULL END) > 42.00)
ORDER BY MaximumRate DESC;

참고 항목

참조

식(Transact-SQL)

SELECT(Transact-SQL)

COALESCE(Transact-SQL)

IIF(Transact-SQL)

CHOOSE(Transact-SQL)