1

SQL Serverの一部のデータをクリーンアップし、2つのテーブルの間に外部キーを追加しようとしています。

削除したいテーブルの1つに孤立した行が大量にあります。次のクエリがMSSQLサーバーで0行を返す理由がわかりません。

-このクエリは行を返しません

select * from tbl_A where ID not in(select different ID from tbl_B)

サブクエリにISNOTNULLを含めると、期待どおりの結果が得られます。

--tbl_Aにはあるが、tbl_Bにはないすべてのレコードを含む行が返されます

select * from tbl_A where ID not in(select * from tbl_B where ID is not null)

ID列はNULL可能であり、NULL値が含まれています。サブクエリだけを実行すると、最初のクエリが期待どおりに1つの余分なNULL行を返すことを除いて、まったく同じ結果が得られます。

4

5 に答える 5

2

これは、NOT INサブクエリの予想される動作です。サブクエリが単一のnull値を返す場合、NOT INどの行とも一致しません。

nullチェックだけを行いたくない場合は、以下を使用しNOT EXISTSます。

select * 
from tbl_A A
where not exists (select distinct ID 
                  from tbl_B b
                  where a.id = b.id)

NOT INが問題を引き起こしている理由については、次の投稿で説明しています。

NOT IN 対 NOT EXISTS 対 LEFT JOIN / IS NULL

NOT EXISTS vs NOT IN

NOT EXISTS と NOT IN と LEFT JOIN WHERE IS NULL の違いは何ですか?

于 2013-01-14T17:11:26.387 に答える
1

NULL と等号 (=) を照合すると、ロジックの観点から true/false ではなく、NULL または UNKNOWN が返されます。たとえば、議論についてはhttp://msdn.microsoft.com/en-us/library/aa196339(v=sql.80).aspxを参照してください。

テーブル B に NULL がないテーブル A に NULL 値を検索することを含めたい場合 (B が「親」であり、A が「子」であり、必要な「外部キー」関係の場合)、2 番目の値が必要になります。ステートメント、次のようなもの。また、両方のテーブルでフィールド名が同じであるため、ID フィールドをテーブル プレフィックスまたはエイリアスで修飾することをお勧めします。最後に、キーとして NULL 値を使用することはお勧めしません。しかし、いずれにせよ:

select * from tbl_A as A where (A.ID not in ( select distinct B.ID from tbl_B as B ))
  or (A.ID is NULL and not exists(select * from tbl_B as B where B.ID is null))
于 2013-01-14T17:13:18.333 に答える
0

ID が決して負でない場合は、次のように考えることができます。

select *
from tbl_A
where coalesce(ID, -1) not in ( select distinct coalesce(ID, -1) from tbl_B )

(またはidが文字列の場合は、 something line を使用しますcoalesce(id, '<null>'))。

これはすべての場合にうまくいくとは限りませんが、コーディング レベルが単純になるという利点があります。

于 2013-01-14T17:23:08.177 に答える
0

ANSI NULL がオフになっている可能性があります。これは null 値を比較するため、null=null は true を返します。

最初のクエリの前に

SET ANSI_NULLS ON
GO
于 2013-01-14T17:12:41.697 に答える
0

問題は、ヌルの比較不可能性です。「not in」を尋ねていて、サブクエリにnullがある場合、それらのnullを「不明」と見なしているため、何かが間違いなく含まれているとは言えません。したがって、3つの値のロジックでは、答えは常に「不明」です。その SQL が使用します。

もちろん、ANSI_NULLS がオンになっていると仮定した場合 (これがデフォルトです)、これをオフにすると、突然 NULLS が同等になり、結果が得られ、おそらく期待どおりの結果が得られます。

于 2013-01-14T17:20:22.467 に答える