SQL Server CASEステートメントはすべての条件を評価するか、最初のTRUE条件で終了しますか?


44

SQL Server(具体的には2008または2012)CASEステートメントはすべてのWHEN条件WHENを評価しますか、またはtrueと評価される句を見つけると終了しますか?条件のセット全体を通過する場合、真と評価された最後の条件が真と評価された最初の条件が上書きしたことを意味しますか?例えば:

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

最後のwhen条件により「NO」と評価されるはずですが、結果は「YES」です。最初のTRUE条件が見つかると終了するようです。誰かがこれが事実であるかどうか確認してください。


5

回答:


46

TRUEと評価される最初の input_expression = when_expression のresult_expressionを返します。

参照 http://msdn.microsoft.com/en-us/library/ms181765.aspx


これは標準的なSQLの動作です。

  • CASE式は最初の真の条件と評価されます。

  • 真の条件が存在しない場合は、そのELSE部分に対して評価されます。

  • 真の条件もELSE部分もない場合、評価はになりNULLます。


2
すべてがtrueと評価される3つのケース条件がある場合、trueと評価される最初の1つのタスクのみが実行され、他の2は実行されないことを確認したいだけです)。私の質問のクエリ例から、これは事実のようです。確認したかっただけです。また、SQLがCASE条件を上から下に読み取ることを期待していました。ありがとう!
フアン・ベレス

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からのリンクを参照してください。

Oracleは常に短絡評価を行います。11.2 SQL Language Referenceを参照してください。または、以下を比較します(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;

この同じテストは、ゼロ除算に対してNULLを返すため、MySQLでは実行できません。(SQLフィドル


どのようにこの?:についてSQL-フィドル
ypercubeᵀᴹ

1
フィドルはSQL-Serverに関するものです。アーロンの答えは次のとおりです。最初の引数がNULLでなくても、SQL ServerはCOALESCE関数をすべて読み取りますか?
ypercubeᵀᴹ

@ypercubeそれは本当に興味深い動作です。else部分で実行されるコードを評価していますが、他のWHEN式が存在するかどうか、およびゼロによる除算がMIN内にあるかどうかによって、それを無視するようです。参照してくださいsqlfiddle.com/#!6/d41d8/4468
リーRiffel

@ypercubeあなたが投稿したリンクの一部を読んだので、SQL Serverが短絡評価を行うかどうかの答えは-通常は?と言うのに十分なエッジケースがあると言いますか?
リーリッフェル

3
はい、「通常」に同意します。アーロンが答えを指摘しているように、1つのテストで「ケースは常に短絡」を反証するのに十分です。しかし、通常はそうです。
ypercubeᵀᴹ

7

MS SQL Serverも短絡評価を使用しているようです。

次のテストでは、3つのテストがあります。1つ目は常に真で、2つ目はテーブルを参照せずに失敗し、3つ目はデータが考慮されている場合にのみ失敗します。
この特定の実行では、両方の行が正常に返されます。最初のWHEN、または最初と2番目をコメントアウトすると、エラーが発生します。

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 whenステートメントがテーブルの列値の評価を含み、テーブルの最初の行がこの条件を満たさない場合、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では、最初の真のオプションでcaseステートメントを終了します。複数の真の値が存在する可能性がある場合は、シーケンスの早い段階で優先回答を配置します。


質問はSQL Serverについてです。
ジェームズアンダーソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.