- 締切済み
SQLの問題で解答を見ても腑に落ちません
問題集の答えが腑に落ちないのでどなたかわかりやすく説明いただけますでしょうか? EMP表 EMPNO ENAME SAL MGR DEPTNO -------------------------------------- 1000 SCOTT 1000 NULL 10 1010 ADAMS 2000 1000 10 1030 TAYLOR 600 1000 30 1050 MILLER 800 1030 10 以下の副問い合わせを使ったSELECT文を実行した。検索されるデータ件数を選びなさい。 select empno,ename from emp where empno not in (select mgr from emp); A:0件 B:1件 C:2件 D:3件 解答はAの0件なのですが、なぜ0件なのでしょうか? 当方の解釈ですと、副問い合わせでmgrが(NULL,1000,1030)となり where empno not in (NULL,1000,1030) で 「empnoがNULLでも1000でも1030でもない件数」 となり、empnoが1010と1050の行が検索され、cの2件が正解なのでは? と思っているのですが・・・ 間違いをわかりやすく教えていただけますでしょうか? 宜しくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- choconamacream
- ベストアンサー率44% (152/338)
他の解答者さんもおっしゃっているように、論理演算子「AND」の問題ですね。(質問者さんは、どうやら比較演算子「NOT IN」の方は理解されているようですし。) >nullが検索されるとなぜ0件なのか教えていただけますでしょうか。 通常は、0『偽(FALSE)』か1『真(TRUE)』 のどちらかなのですが、NULLがきた場合、AND演算子では検索の処理を強制終了したような感じとなって「0件」、つまり該当する件数無しとする訳ですね。 where empno <> NULL AND empno <> 1000 AND empno <> 1030 は、0です。
- 3rd_001
- ベストアンサー率66% (115/174)
こういうときはマニュアルを参照しましょう。以下に解説されております。マニュアルどおりの動きですよ。 http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/conditions.html#10694 >NOT IN演算子に続くリストの中のいずれかの項目がNULLの場合は、すべての行はFALSEまたは不明(UNKNOWN)と評価されます(行は戻されません)。 >たとえば、次の文ではそれぞれの行に対して文字列'True'が戻されます。 > >SELECT 'True' FROM employees > WHERE department_id NOT IN (10, 20); > >ただし、次の文では行は戻されません。 > >SELECT 'True' FROM employees > WHERE department_id NOT IN (10, 20, NULL); > >この例で行が戻されないのは、WHERE句の条件が次のように評価されるためです。 > >department_id != 10 AND department_id != 20 AND department_id != null > >3番目の条件でdepartment_idとNULLの比較が行われるため、この条件の結果がUNKNOWNとなり、 >式全体の結果がFALSE(department_idを持つ行が10または20と等しいため)となります。 >特に、NOT IN演算子が副問合せを参照するときは、 >このような動作を見逃してしまう可能性があることに注意してください。 > >また、NOT IN条件が、行を戻さない副問合せを参照する場合は、 >次のように、すべての行が戻されます。 > >SELECT 'True' FROM employees > WHERE department_id NOT IN (SELECT 0 FROM DUAL WHERE 1=2);
- dda167
- ベストアンサー率76% (55/72)
NOT INの罠ですね。 以下のページが参考になるでしょう。 3値論理とNULL(http://codezine.jp/article/detail/532?p=1)
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
意地悪な引っ掛け問題に、見事に引っかかってる感じだな。 select empno,ename from emp where empno not in (select mgr from emp); は、0件。 select empno,ename from emp where empno not in (select mgr from emp where mgr is not null); は、2件。 という結果になるのですが、これで理解できるんじゃないですか?
補足
回答ありがとうございます。 しかし、私の理解不足ですが (select mgr from emp where mgr is not null); はnull以外のmgrを検索するので1000と1030が検索され、 結果、empnoが1010と1050の2件 と同じ答えになってしまいます。 nullが検索されるとなぜ0件なのか教えていただけますでしょうか。