2017-03-15 3 views
0

私の場合、同じ構造の2つのテーブルがあります:TableA & TableBそして、私はレコードがAのみB Aに存在するがない2つのレコードがありますが。削除された行を見つける:存在していないvsはありません

私のスクリプトは

SELECT * FROM TableA 
WHERE NOT EXISTS (
    SELECT * FROM TableB 
) 

た、このスクリプトは何も返しません。次に、次のように変更しました:

SELECT ID FROM TableA 
WHERE ID NOT IN (
    SELECT ID FROM TableB 
) 

このスクリプトは正常に動作し、2レコードのIDを返します。


質問:この動作は正常ですか? NOT EXISTSNOT INのメカニズムは何ですか?

私はNOT EXISTSNOT INを比較するいくつかの他の記事を読んでいると、ほとんどの人は99.9%のシナリオでNOT EXISTSを使用することをお勧めし、この場合はNOT EXISTSが適用されないことを0.1%に落ちていますか? あなたは、行のすべての値を見たい場合は、

+3

最初のクエリは、WHERE TableB.id = TableA.id 'のように、条件が欠けています'(ネストされたクエリの内部)。したがって、クエリは文字通り次のように読み込まれます。TableAから同じIDを持つTableBの行が存在しない場所をすべて選択します。 – zerkms

+0

"この場合は、存在しないNOT 0.1%に該当します" ---私は 'IN 'を含むすべての**クエリは' EXISTS'で表現できると言っています。 – zerkms

答えて

3

、その後使用(私はそれは、そのような場合、私を修正してくださいしかし、私の誤った使い方が原因だと考えられる)EXCEPT

SELECT * 
FROM TableA 
EXCEPT 
SELECT * 
FROM TableB; 

の場合

SELECT a.* 
FROM TableA a 
WHERE NOT EXISTS (SELECT 1 FROM TableB b WHERE b.id = a.id); 

私は強くサブクエリでNOT INNOT EXISTSを使用することをお勧めします:あなたは、あなたが相関句を必要とし、正しくNOT EXISTSを使用します。 NOT INは、b.idの場合、まったく行を返しません。NULLです。それは通常意図されているものではありません。 NOT EXISTSは、期待されるセマンティクスに一致します。

+0

ありがとう、私はなぜ 'NOT IN'が存在したのか、' NOT EXISTED'が@zerkmsとして使用されているスーパーセットであるのかと疑問に思います。 – shole

+0

@shole。 。 。第一に、彼らは異なったセマンティクスを持っています(微妙な差異ですが、違います)。第2に、 'NOT IN'は定数リストで動作します。第三に、SQLは物事を一つの方法でしか行うと主張していません。 '<> ALL'と' left join'を含む他のメソッドがあります。それは言語がどのように設計されたかです。 –

1

NOT INの式には注意が必要です。 A NOT IN(B,C,D)という表現は基本的には(A<>B AND A<>C AND A<>D)を意味します。いずれかの値がNULLの場合、式全体がNULLになります。

(IDがNULL可能列でない限り)ので、あなたの例に適用される表現で正しく行われていませんが、次のようになります。

SELECT ID FROM TableA 
WHERE ID NOT IN (
    SELECT ID FROM TableB WHERE ID IS NOT NULL 
) 
+0

ありがとう、私は物事をより明確にするこの記事を見つけました:http:// stackoverflow。com/questions/129077/not-in-clause-and-null-values – shole

関連する問題