2016-05-17 8 views
4

なんらかの理由で、これらの2つのSQL文が同等ではありません。なぜ誰かが理解を助けることができますか?mySQLでのIN/NOT INの使用

SELECT N, IF(P IS NULL, 'Root', IF(N NOT IN (SELECT P FROM BST), 'Leaf', 'Inner')) 
FROM BST 
ORDER BY N; 

SELECT N, IF(P IS NULL, 'Root', IF(N IN (SELECT P FROM BST), 'Inner', 'Leaf')) 
FROM BST 
ORDER BY N; 

P.S.これはHackerRankのバイナリサーチツリーの問題です。 https://www.hackerrank.com/challenges/binary-search-tree-1

+0

NOT IN(null)は多くのユーザーをだましています。 – jarlh

答えて

2

上記のjarlhのコメントは正しいです。すなわち、テストIFNULLまたは 'is null'を除いてTRUEとNULLを比較するものはありません。したがって、クエリ:

(SELECT P FROM BST) 

が1つのNULL値を返す場合、2つのSQL文は異なる結果を返します。これは簡単に以下の2つのSQL文で実証することができます。

select if (1 in (select null), 'a', 'b') => 'b' 

select if (1 not in (select null), 'b', 'a') => 'a' 
0

いいえ。 NOT INには、基になるテーブルの値がNULLの場合に、奇妙な意味があります。この場合、文節はすべての行を除外します。このため

は、私がNOT EXISTSがより良い選択肢だと思う:

NOT EXISTS (SELECT 1 FROM BST WHERE BST.P = BST.N) 

あなたは、2つのサブクエリにWHERE P IS NOT NULLを追加することによってこの問題を解決することができます。

0

声明X IN (A,B)X=A OR X=Bに変換されます。 ORを使用する場合、1つのステートメントだけがTRUEでなければなりません。 AまたはBのいずれかがNULLの場合、比較部分はNULLに等しくなりますが、他の部分は結果を得ることができます。

たとえば、Bがnullで、Aが実際にXと等しいとします。これはTRUEまたはNULLです。これはTRUEです。

ステートメントX NOT (A,B)X<>A AND X<>Bに変換されます。 ANDを使用する場合、結果全体がTRUEになるには、すべてのステートメントがTRUEである必要があります。一方の側がNULLの場合、文全体はNULLに解決され、TRUEではありません。

BがNULLでXがAでない場合、TRUE OR NULLを返し、最後にNULLを取得します。