2013-01-16 69 views
32

假设我有以下2个表:SQL服务器加入失踪NULL值

 Table1:        Table2: 
Col1:  Col2:  Col3:    Col1:  Col2:  Col4: 
a   b   c     a   b   d 
e   <null> f     e   <null>  g 
h   i   j     h   i   k 
l   <null> m     l   <null>  n 
o   <null> p     o   <null>  q 

现在,我想加入上Col1Col2这些表,并带回整套的样子:

 Result: 
Col1:  Col2:  Col3:  Col4: 
a   b   c   d 
e   <null> f   g 
h   i   j   k 
l   <null> m   n 
o   <null> p   q 

于是,我试着像SQL:

SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 
FROM Table1 INNER JOIN Table2 
ON Table1.Col1 = Table2.Col1 
AND Table1.Col2 = Table2.Col2 

但它不匹配日ËNULLCol2值,所以我结束了:

 Result: 
Col1:  Col2:  Col3:  Col4: 
a   b   c   d 
h   i   j   k 

我怎样才能得到我要寻找的结果?

谢谢!

回答

45

您可以更明确一些联接:

SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 
FROM Table1 INNER JOIN 
    Table2 
     ON (Table1.Col1 = Table2.Col1 or Table1.Col1 is NULL and Table2.Col1 is NULL) AND 
     (Table1.Col2 = Table2.Col2 or Table1.Col2 is NULL and Table2.Col2 is NULL) 

在实践中,我会更容易在连接条件使用coalesce()

SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 
FROM Table1 INNER JOIN 
    Table2 
    ON (coalesce(Table1.Col1, '') = coalesce(Table2.Col1, '')) AND 
     (coalesce(Table1.Col2, '') = coalesce(Table2.Col2, '')) 

''将是一个值不任一表格。

只是一句谨慎。在大多数数据库中,使用这些结构中的任何一个都会阻止使用索引。

+1

喜@戈登 - linoff,你的答案是最珍贵的在这种情况下。非常感谢 –

10

尝试使用ISNULL功能:

SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 
FROM Table1 
INNER JOIN Table2 
    ON Table1.Col1 = Table2.Col1 
    AND ISNULL(Table1.Col2, 'ZZZZ') = ISNULL(Table2.Col2,'ZZZZ') 

哪里'ZZZZ'是一些任意值从来没有在表中。

+5

这引入了我想要避免的魔术值,除非绝对必要 –

+0

这会很好地工作,但假定'0'不在另一行的其他地方使用。 – PinnyM

+0

是的,我更喜欢@戈登的回答,只是提供一个替代方案。我可能会使用一个不同的值,我知道不能在'ZZZZ'之类的返回值中表示:-) – sgeddes

5

脏,快速劈:

SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 
FROM Table1 INNER JOIN Table2 ON Table1.Col1 = Table2.Col1 
AND ((Table1.Col2 = Table2.Col2) OR (Table1.Col2 IS NULL AND Table2.Col2 IS NULL)) 
+0

谢谢,@Jap - 正是我在找的东西...... Gordon击败了你,但谢谢你回答! –

16

使用左外连接,而不是内部加入到包括与NULLS行。

SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 
FROM Table1 LEFT OUTER JOIN 
    Table2 ON Table1.Col1 = Table2.Col1 
    AND Table1.Col2 = Table2.Col2 

欲了解更多信息,请参见这里:http://technet.microsoft.com/en-us/library/ms190409(v=sql.105).aspx

+0

适合我。简单而干净。 – Kuvalya

+0

这并不回答原来的问题。如果找不到匹配项,您的解决方案将包含table2的空行。看看OP的问题 – AaA

+0

这两个表中的第二行为我工作..谢谢! –

-1

你可以像那样的地图

select * from tableA a 
join tableB b on isnull(a.colID,'') = isnull(b.colId,'')