SQLのサブクエリの結果セットがない場合、それはどのように評価されますか?


おそらく、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')

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2007/01/22 14:53:08
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:b-wind No.2

回答回数3344ベストアンサー獲得回数440

ポイント35pt

行を返さないサブクエリは、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 を使用するほうが適切です。

id:witt

納得できました。

そもそもこの質問をしたのは、次のような普通のサブクエリの使い方をしたとき、

select * from t1 where col1 = (select col2 from t2 where col3 = 'hoge')

サブクエリが行を返さなかったら、どう評価されるのだろうと思ったのがきっかけでした。

エラーになるわけではないので、おそらくNULL扱いされているのだろうと。

それを知りたかったわけです。

すっきりしました。ありがとうございました。

2007/01/22 14:52:31

その他の回答1件)

id:b-wind No.1

回答回数3344ベストアンサー獲得回数440

ポイント35pt

http://msdn2.microsoft.com/ja-jp/library/ms188336.aspx

戻り値

サブクエリが行を含む場合、TRUE を返します。

なので4のサブクエリが今日を返さないのであれば FALSE と評価されます。

exists を使う3,4とサブクエリそのものを評価する1,2ではそもそも問題の質が違うように思うのですが。

id:witt

ご回答ありがとうございます。


行を返さないサブクエリは、NULLとは違う「行を返さない」という評価になるのか、

これもNULL扱いになるのか、混乱してます。

もし前者が正しいならば、②のWHERE句がどうしてTRUEになるのか疑問です。

2007/01/22 13:53:38
id:b-wind No.2

回答回数3344ベストアンサー獲得回数440ここでベストアンサー

ポイント35pt

行を返さないサブクエリは、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 を使用するほうが適切です。

id:witt

納得できました。

そもそもこの質問をしたのは、次のような普通のサブクエリの使い方をしたとき、

select * from t1 where col1 = (select col2 from t2 where col3 = 'hoge')

サブクエリが行を返さなかったら、どう評価されるのだろうと思ったのがきっかけでした。

エラーになるわけではないので、おそらくNULL扱いされているのだろうと。

それを知りたかったわけです。

すっきりしました。ありがとうございました。

2007/01/22 14:52:31
  • id:icchan0000
    えっとBooks Onlineより。


    <span style="font-weight:bold;">EXISTS を使ったサブクエリ</span>

    サブクエリがキーワード EXISTS で導かれる場合、このサブクエリは存在検査として機能します。1 つ上のレベルのクエリの WHERE 句は、サブクエリによって返される行の存在を検査します。<span style="font-weight:bold;">サブクエリは実際にはデータを生成せず、TRUE または FALSE の値を返します。</span>


    <span style="font-weight:bold;">比較演算子を使ったサブクエリ</span>

    修飾されていない比較演算子 (後ろに ANY や ALL がない比較演算子) で導かれるサブクエリは、IN によって導かれるサブクエリと同様に、値のリストでなく<span style="font-weight:bold;">単一の値を返す必要</span>があります。リストの値が返された場合、Microsoft® SQL Server™ ではエラーメッセージを表示します。


    ②は、後者の場合で、「単一の値」として評価されるので、結果を返さない場合はNULLと判断されます。

    ④は前者の場合で、True or Falseを返します。


    サブクエリは、コンテクストによって評価方法は変わるってことだと思います。
  • id:witt
    コメントありがとございます。
    Books Onlineのような公式なドキュメントの情報は助かります。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません