web-dev-qa-db-ja.com

NULL値でのSQL内部結合

参加しています

SELECT * FROM Y
INNER JOIN X ON ISNULL(X.QID, 0) = ISNULL(y.QID, 0) 

このようなJoinのIsnullは、速度を低下させます。条件付き結合を持つようなものです。このようなものに回避策はありますか? QIDがNullであるレコードがたくさんあります

誰もがデータの変更を伴わない回避策を持っています

37
Rico

2つのオプションがあります

INNER JOIN x
   ON x.qid = y.qid OR (x.qid IS NULL AND y.qid IS NULL)

またはより簡単

INNER JOIN x
  ON x.qid IS NOT DISTINCT FROM y.qid
58
Evan Carroll

内部結合構文を使用することにコミットしていますか?

そうでない場合は、この代替構文を使用できます。

SELECT * 
FROM Y,X
WHERE (X.QID=Y.QID) or (X.QUID is null and Y.QUID is null)
7
JohnFx

この記事では、この問題に関する良い議論があります 。使用できます

SELECT * 
FROM Y
INNER JOIN X ON EXISTS(SELECT X.QID 
                       INTERSECT 
                       SELECT y.QID);
5
Martin Smith

私は、結合があなたの望むことさえしないと確信しています。テーブルaにnull qidの100レコードがあり、テーブルbにnull qidの100レコードがある場合、記述された結合は相互結合を行い、それらのレコードに対して10,000の結果を出します。次のコードを見て例を実行すると、おそらく最後のコードが意図した結果セットに近いと思います。

create table #test1 (id int identity, qid int)
create table #test2 (id int identity, qid int)

Insert #test1 (qid)
select null
union all
select null
union all
select 1
union all
select 2
union all
select null

Insert #test2 (qid)
select null
union all
select null
union all
select 1
union all
select 3
union all
select null


select * from #test2 t2
join #test1 t1 on t2.qid = t1.qid

select * from #test2 t2
join #test1 t1 on isnull(t2.qid, 0) = isnull(t1.qid, 0)


select * from #test2 t2
join #test1 t1 on 
 t1.qid = t2.qid OR ( t1.qid IS NULL AND t2.qid IS NULL )


select t2.id, t2.qid, t1.id, t1.qid from #test2 t2
join #test1 t1 on t2.qid = t1.qid
union all
select null, null,id, qid from #test1 where qid is null
union all
select id, qid, null, null from #test2  where qid is null
3
HLGEM

Y.QIDからnull値を含める場合、最速の方法は

SELECT * FROM Y LEFT JOIN X ON y.QID = X.QID

注:このソリューションは、左のテーブル、つまりY(上記の場合)からnull値が必要な場合にのみ適用できます。

さもないと INNER JOIN x ON x.qid IS NOT DISTINCT FROM y.qidは正しい方法です

2
ni3nas