SQL Server CASE 문은 모든 조건을 평가하거나 첫 번째 TRUE 조건에서 종료됩니까?


44

SQL Server (특히 2008 또는 2012) CASE문은 모든 WHEN조건 WHEN을 평가합니까 아니면 true로 평가 되는 절을 찾으면 종료 됩니까? 전체 조건 집합을 통과하는 경우 true로 평가되는 마지막 조건이 true로 평가 된 첫 번째 조건이 덮어 쓴다는 의미입니까? 예를 들면 다음과 같습니다.

SELECT
    CASE
        WHEN 1+1 = 2 THEN'YES'
        WHEN 1+1 = 3 THEN 'NO'
        WHEN 1+1 = 2 THEN 'NO' 
    END

마지막 조건이 "아니오"로 평가 되더라도 결과는 "예"입니다. 첫 번째 TRUE 조건을 찾으면 종료되는 것 같습니다. 이는 경우 누군가가 확인하시기 바랍니다 수있는 경우 .


5
매우 밀접한 관련 : SQL Server는 첫 번째 인수가 NULL이 아닌 경우에도 모든 COALESCE 함수를 읽습니까? (같은 COALESCE()로 변환됩니다 CASE. 표현)
ypercubeᵀᴹ

답변:


46

참으로 평가 되는 첫 번째 input_expression = when_expression 의 result_expression을 반환 합니다 .

참조 http://msdn.microsoft.com/en-us/library/ms181765.aspx


이것은 표준 SQL 동작입니다.

  • CASE표현은 최초의 진정한 상태로 평가합니다.

  • 실제 조건이 없으면 ELSE부품으로 평가됩니다 .

  • 실제 조건이없고 ELSE부분 이 없으면로 평가됩니다 NULL.


2
방금 모두 true로 평가되는 3 가지 사례 조건이있는 경우 true로 평가되는 첫 번째 사례의 작업 만 실행되도록하고 다른 2 개는 수행하지 않기를 원했습니다. ). 내 질문의 예제 쿼리에서 이것은 사실 인 것 같습니다. 방금 확인하고 싶었습니다. 또한 SQL이 CASE 조건을 위에서 아래로 읽는 것을 희망했습니다. 감사!
Juan Velez

15

SQL Server는 일반적으로 CASE 문의 단락 평가 ( SQLFiddle )를 수행합니다.

--Does not fail on the divide by zero.
SELECT 
   CASE 
      WHEN 1/1 = 1 THEN 'Case 1'
      WHEN 2/0 = 1 THEN 'Case 2'
   END;

--Fails on the divide by zero.
SELECT 
   CASE 
      WHEN 1/1 = 99 THEN 'Case 1'
      WHEN 2/0 = 99 THEN 'Case 2'
   END;  

그러나 SQL Server 2012부터 올바르게 단락되지 않는 몇 가지 유형의 명령문이 있습니다. 주석에서 ypercube의 링크를 참조하십시오.

오라클은 항상 단락 평가를 수행 합니다. 참고 항목 11.2 SQL 언어 참조 . 또는 다음을 비교하십시오 ( SQLFiddle ).

--Does not fail on the divide by zero.
SELECT
  CASE 
    WHEN 1/1 = 1 THEN 'Case 1'
    WHEN 2/0 = 1 THEN 'Case 2'
  END
FROM dual;


--Fails on the divide by zero.
SELECT
  CASE 
    WHEN 1/1 = 99 THEN 'Case 1'
    WHEN 2/0 = 99 THEN 'Case 2'
  END
FROM dual;

이 테스트는 0으로 나누기 위해 NULL을 반환하기 때문에 MySQL에서 수행 할 수 없습니다. ( SQL 피들 )


이건 어때요? : SQL-Fiddle
ypercubeᵀᴹ

1
바이올린 은 SQL-Server에 관한 것 입니다. 이것은 Aaron의 대답입니다. 첫 번째 인수가 NULL이 아니더라도 SQL Server는 모든 COALESCE 함수를 읽습니까?
ypercubeᵀᴹ

@ypercube 정말 흥미로운 행동입니다. else 부분에서 실행될 코드를 평가하고 있지만 다른 WHEN 표현식이 존재하고 0으로 나누기가 MIN 안에 있는지 여부에 따라 코드를 무시하는 것 같습니다. 참조 sqlfiddle.com/#!6/d41d8/4468
레이 Riffel

@ypercube 이제 여러분이 게시 한 링크 중 일부를 읽었으므로 SQL Server가 단락 평가를 수행하는지 여부에 대한 대답이 일반적이라고 말할만한 충분한 경우가 있다고 말할 수 있습니까?
레이 리펠

3
예, "보통"에 동의합니다. Aaron이 자신의 답변을 지적한 것처럼 하나의 테스트만으로 "CASE 항상 단락"을 반증 할 수 있습니다. 그러나 보통 그렇습니다.
ypercubeᵀᴹ

7

MS SQL Server는 단락 평가도 사용하는 것으로 보입니다.

다음 테스트에는 3 가지 테스트가 있습니다. 첫 번째는 항상 참이고 두 번째는 테이블을 참조하지 않고 실패하고 세 번째는 데이터를 고려할 때만 실패합니다.
이 특정 실행에서 두 행이 모두 성공적으로 반환됩니다. 첫 번째 WHEN 또는 첫 번째 및 두 번째 주석을 주석 처리하면 오류가 발생합니다.

CREATE TABLE casetest (test varchar(10))
GO
INSERT INTO casetest VALUES ('12345'),('abcdef')
GO

SELECT CASE WHEN LEN(test)>1 THEN test
        WHEN 1/0 = 1 THEN 'abc'
        WHEN CAST(test AS int) = 1 THEN 'def'
        END
FROM casetest
GO

1

WHERE조건에 사용 된 case 문과 첫 번째 case 문이 테이블에서 열 값을 평가하는 것을 포함하고 테이블의 첫 번째 행이이 조건을 만족하지 않으면 case 문은 다음 case when 문으로 이동합니다.

declare @tbl table(id int)
insert into @tbl values(1)
insert into @tbl values(2)
insert into @tbl values(3)

--Fails on the divide by zero.
SELECT * FROM @tbl
where  CASE 
        WHEN id = 2 THEN 1 -- first row in table will not satisfy the condition
        WHEN 2/0 = 1 THEN 1
        ELSE 0
      END =1

-- when filter the records to only who will staisfy the first case when condition, it 
will not fail on the divide by zero
SELECT * FROM @tbl
where ID=2 and -- first row in table will  satisfy the condition
  CASE 
    WHEN id = 2 THEN 1
    WHEN 2/0 = 1 THEN 1
    ELSE 0
  END =1

1

MySQL에서는 첫 번째 true 옵션에서 case 문을 종료합니다. 여러 개의 true 값을 사용할 가능성이있는 경우 우선 순위를 우선 순위에 두십시오.


문제는 SQL Server에 관한 것입니다.
제임스 앤더슨
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.