SQL内部联接空值

时间:2010-02-04 18:32:53

标签: sql sql-server join null

我有一个加入

SELECT * FROM Y
INNER JOIN X ON ISNULL(X.QID, 0) = ISNULL(y.QID, 0) 
像这样的加入中的

Isnull会让它变慢。这就像有条件的加入。 有什么工作可以解决这个问题吗? 我有很多记录QID是空的

任何人都有解决方法,无需修改数据

7 个答案:

答案 0 :(得分:57)

您有两个选择

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

答案 1 :(得分:7)

您是否已承诺使用Inner join语法?

如果没有,你可以使用这种替代语法:

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

答案 2 :(得分:5)

This article has a good discussion on this issue。你可以使用

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

答案 3 :(得分:3)

我很确定连接甚至不能做你想要的。如果表a中有100条带有空qid的记录和表b中带有空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

答案 4 :(得分:2)

如果要从Y.QID中包含空值,则最快的方式是

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

注意:此解决方案仅适用于您需要来自Left表的空值,即Y(在上述情况下)。

否则 INNER JOIN x ON x.qid IS NOT DISTINCT FROM y.qid 是正确的做法

答案 5 :(得分:-1)

基本上你想将两个表连接在一起,它们的QID列都是不是 null,对吗?但是,您没有强制执行任何其他条件,例如两个QID值(这对我来说似乎很奇怪,但确定)。像以下一样简单(在MySQL中测试)似乎可以做你想要的:

SELECT * FROM `Y` INNER JOIN `X` ON (`Y`.`QID` IS NOT NULL AND `X`.`QID` IS NOT NULL);

这使得Y中的每个非空行都连接到X中的每个非空行。

更新:Rico说他也想要带有NULL值的行,为什么不呢:

SELECT * FROM `Y` INNER JOIN `X`;

答案 6 :(得分:-1)

您也可以使用coalesce功能。我在PostgreSQL中对此进行了测试,但它也适用于MySQLMS SQL server

INNER JOIN x ON coalesce(x.qid, -1) = coalesce(y.qid, -1)

在评估之前,这会将NULL替换为-1。因此-1中必须没有qid