おそらく、NULLと評価されるだろうと思ったので、下記のような検証コードを書きました。
環境は、Microsoft SQL Server 2000です。
その結果、②ではWHERE句はTRUEと評価されるのに、④ではTRUEと評価されない(FALSEかUNKNOWN?)のはつじつまが合わないと思いました。
これらについて解説をいただきたいと思います。
USE pubs
-- ① 次のSQL文はWHERE句はTRUE
SELECT * FROM jobs WHERE (SELECT NULL) IS NULL
-- ② 次のSQL文はWHERE句がTRUE
SELECT * FROM jobs WHERE (SELECT title FROM titles WHERE title='abcd') IS NULL
-- ③ 次のSQL文はWHERE句はTRUE
SELECT * FROM jobs WHERE exists (SELECT NULL)
-- ④ 次のSQL文はWHERE句はTRUEではない
SELECT * FROM jobs WHERE exists (SELECT title FROM titles WHERE title='abcd')
行を返さないサブクエリは、NULLとは違う「行を返さない」という評価になるのか
スカラーとして評価する場合、直感的には NULL か unknown になるような気がします。
ただ、実装ごとに違いそうなのでどれが正解かは自信がありません。
スカラーとしての評価に、「行を返さない」という概念はありませんから。
SQL Server は詳しくないので、MySQL の例ですが、スカラーとしての評価は NULL になります。
http://www.mysql.org/doc/refman/4.1/ja/scalar-subqueries.html
ただ、exits はあくまでサブクエリが行を返すかどうかを判定する構文です。スカラーとしての評価を関数に渡しているわけではありません。
http://www.mysql.org/doc/refman/4.1/ja/exists-and-not-exists-sub...
利用するシチュエーションにも寄りますが、サブクエリーの結果が空かどうかを判定するには exists を使用するほうが適切です。
http://msdn2.microsoft.com/ja-jp/library/ms188336.aspx
戻り値
サブクエリが行を含む場合、TRUE を返します。
なので4のサブクエリが今日を返さないのであれば FALSE と評価されます。
exists を使う3,4とサブクエリそのものを評価する1,2ではそもそも問題の質が違うように思うのですが。
ご回答ありがとうございます。
行を返さないサブクエリは、NULLとは違う「行を返さない」という評価になるのか、
これもNULL扱いになるのか、混乱してます。
もし前者が正しいならば、②のWHERE句がどうしてTRUEになるのか疑問です。
行を返さないサブクエリは、NULLとは違う「行を返さない」という評価になるのか
スカラーとして評価する場合、直感的には NULL か unknown になるような気がします。
ただ、実装ごとに違いそうなのでどれが正解かは自信がありません。
スカラーとしての評価に、「行を返さない」という概念はありませんから。
SQL Server は詳しくないので、MySQL の例ですが、スカラーとしての評価は NULL になります。
http://www.mysql.org/doc/refman/4.1/ja/scalar-subqueries.html
ただ、exits はあくまでサブクエリが行を返すかどうかを判定する構文です。スカラーとしての評価を関数に渡しているわけではありません。
http://www.mysql.org/doc/refman/4.1/ja/exists-and-not-exists-sub...
利用するシチュエーションにも寄りますが、サブクエリーの結果が空かどうかを判定するには exists を使用するほうが適切です。
納得できました。
そもそもこの質問をしたのは、次のような普通のサブクエリの使い方をしたとき、
select * from t1 where col1 = (select col2 from t2 where col3 = 'hoge')
サブクエリが行を返さなかったら、どう評価されるのだろうと思ったのがきっかけでした。
エラーになるわけではないので、おそらくNULL扱いされているのだろうと。
それを知りたかったわけです。
すっきりしました。ありがとうございました。
納得できました。
そもそもこの質問をしたのは、次のような普通のサブクエリの使い方をしたとき、
select * from t1 where col1 = (select col2 from t2 where col3 = 'hoge')
サブクエリが行を返さなかったら、どう評価されるのだろうと思ったのがきっかけでした。
エラーになるわけではないので、おそらくNULL扱いされているのだろうと。
それを知りたかったわけです。
すっきりしました。ありがとうございました。