88

假设我有以下 2 个表:

      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

但它与 中的NULL值不匹配Col2,所以我最终得到:

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

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

谢谢!

4

10 回答 10

127

您可以明确说明连接:

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, ''))

Where''将是不在任何一个表中的值。

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

于 2013-01-16T19:17:20.833 回答
46

使用左外连接而不是内连接来包含带有 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

于 2013-07-15T19:38:11.047 回答
17

尝试使用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'永远不会出现一些任意值。

于 2013-01-16T19:17:27.260 回答
14

肮脏而快速的破解:

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))
于 2013-01-16T19:19:56.133 回答
1

你可以像那样映射

select * from tableA a
join tableB b on isnull(a.colID,'') = isnull(b.colId,'')
于 2015-07-04T13:20:08.637 回答
1

由于某种原因,我无法让它与外部连接一起工作。

所以我用:

SELECT * from t1 where not Id in (SELECT DISTINCT t2.id from t2)
于 2019-04-09T08:13:37.020 回答
0

尝试在连接中使用附加条件:

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)
   )
于 2019-12-17T12:46:37.907 回答
0

一些 SQL 实现有一个特殊的 Null 安全相等运算符。

例如雪花有EQUAL_NULL所以你可以做

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

于 2021-10-27T10:19:46.440 回答
0
declare @Table1 as Table(Col1 varchar(1),Col2 varchar(1), Col3 varchar(1))
declare @Table2 as Table(Col1 varchar(1),Col2 varchar(1), Col4 varchar(1))
insert into @Table1
values('a',          'b',     'c'),
('e',          null,    'f'), 
('h',          'i'  ,   'j'), 
('l',          null  ,  'm'), 
('o',          null  ,  'p') 
insert into @Table2
values('a',          'b',     'd'),
('e',          null,    'g'), 
('h',          'i'  ,   'k'), 
('l',          null  ,  'n'), 
('o',          null  ,  'q') 


select * from @Table1 tbl1
join @Table2 tbl2
on tbl1.Col1 =tbl2.Col1
and isnull(tbl1.Col2,0) =isnull(tbl2.Col2,0)

输出:

 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
于 2021-07-07T16:05:20.413 回答
-1

唯一正确的答案是不要连接具有空值的列。这会很快导致不受欢迎的行为。

例如 isnull(b.colId,''): 如果数据中有空字符串会怎样?连接可能是重复的行,我猜在这种情况下不打算这样做。

于 2020-08-03T07:17:07.347 回答