左连接没有给出正确的输出

时间:2016-06-14 07:29:52

标签: sql sql-server outer-join

我有2张桌子

TABLEA

Accountid   
-----------  
10  
11  
12  

tableB

Accountid   |   Date        |   
--------------------------------------------    
10      |   2016-02-02  |   
11      |   2016-02-02  |   
11      |   2016-02-02  |    
15      |   2016-02-03  |   

我期待输出像

Accountid   |   ID  |   
------------------------------------    
10      |   10  |   
11      |   11  |   
12      |   NULL    |   

我正在运行此查询

select A.accountid,b.accountid as ID 
from tableA as A 
left join tableB as B on a.accountid=b.accountid 
where b.date between '2016-02-02' and '2016-02-02'

但它给了我输出,我不知道我哪里出错了

Accountid   |   ID  |   
----------------------------------- 
10      |   10  |   
11      |   11  |   

我正在使用MSSQL数据库。

4 个答案:

答案 0 :(得分:1)

WHERE子句中出现左连接的右表的任何字段时,此连接的行为将类似于INNER JOIN

要获得预期结果,您的查询应该是这样的

select A.accountid,b.accountid as ID 
from tableA as A 
left join tableB as B on a.accountid=b.accountid and 
                         b.date between '2016-02-02' and '2016-02-02'

答案 1 :(得分:0)

试试这个:

select A.accountid,b.accountid as ID 
from tableA as A left join tableB as B on a.accountid=b.accountid 
where b.date is null or b.date between '2016-02-02' and '2016-02-02'

原因是,对于AccountID 12,b.date实际上是null(因为tableB中没有行)。因此,如果在查询中允许date为null,则只会获得该行的结果。

答案 2 :(得分:0)

如果b不存在(id = 12),则where子句返回false。  如果你想看到id = 12的行,你必须在你的“ON”条款中包含你的测试(在“2016-02-02”和“2016-02-02”之间的b.date):

   select A.accountid,b.accountid as ID from tableA as A left join tableB as B 
on a.accountid=b.accountid and b.date between '2016-02-02' and '2016-02-02'

答案 3 :(得分:0)

原因是因为select的WHERE子句在LEFT JOIN之后执行

所以,第一个sql server将按预期提取数据,行为12-NULL,

然后它将被过滤掉并通过WHERE子句从输出中删除

您可以按照@JaydipJ和@RémyBaron

的建议在JOIN条件下移动日期过滤器

或以这种方式在JOIN之前过滤tableB:

select A.accountid,b.accountid as ID 
from tableA as A 
left join (
  select * 
  from tableB 
  where b.date between '2016-02-02' and '2016-02-02'
) as B on a.accountid=b.accountid