SQL Server(具体的には2008または2012)CASE
ステートメントは、すべてのWHEN
条件を評価しますか、それとも、trueと評価されるWHEN
句を見つけたら終了しますか?条件のセット全体を通過する場合、それは、trueと評価された最後の条件が、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条件が見つかると終了するようです。誰かがこれがcaseであるかどうかを確認してください。
•firstinput_expression = when_expressionのresult_expressionを返し、TRUEと評価。
リファレンス http://msdn.Microsoft.com/en-us/library/ms181765.aspx
これは標準SQLの動作です。
CASE
式は最初の真の条件に評価されます。
真の条件がない場合は、ELSE
部分として評価されます。
真の条件がなく、ELSE
部分もない場合、NULL
と評価されます。
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言語リファレンス を参照してください。または、次の比較( 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フィドル )
MS SQL Serverも短絡評価を使用しているようです。
次のテストでは、3つのテストがあります。 1つ目は常にtrue、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
MySQLでは、最初のtrueオプションでcaseステートメントを終了します。複数の真の値の可能性がある場合は、優先する回答をシーケンスの前に配置する必要があります。
WHERE
条件で使用されるcaseステートメントと最初のcaseステートメントがテーブルの列値の評価に関係し、テーブルの最初の行がこの条件を満たさない場合、caseステートメントは次のケースに進みますステートメント。
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