左连接然后内部连接使用sql不正确的结果?

时间:2017-03-20 06:58:20

标签: sql sql-server

我有3张桌子

drop table #temp;
create table #temp(id int,name varchar(50))

insert into #temp values(1,'ABC');
insert into #temp values(2,'XYZ');
select * from #temp

drop table #table_link;
create table #table_link(id int,temp_id int,temp2_id int)

insert into #table_link values(1,1,1);
insert into #table_link values(2,1,2);

select * from #table_link

drop table #temp2;
create table #temp2(id int,active_tag bit);
insert into #temp2 values(1,0)
insert into #temp2 values(2,1)

我想要的结果是使用#table_link获取#temp表和active_tag = 1中的所有行。

id  |  name | #temp2_id |
1   |  ABC  |  2        |
2   |  XYZ  |  NULL     |

我试过查询

select * from #temp t
left join #table_link tl on tl.temp_id=t.id
inner join  #temp2 t2 on t2.id=tl.temp2_id and t2.active_tag=1 

在这个查询中我只得到ABC行。我使用了左连接,为什么XYZ行没有得到。当前结果就是这样的

id  |  name | #temp2_id |
1   |  ABC  |  2        |
  

请解释为什么它不起作用?

3 个答案:

答案 0 :(得分:1)

select t.id,t.Name,tl.temp2_id from #temp t
left join #table_link tl on tl.temp_id=t.id
AND EXISTS (SELECT 1 from #temp2 t2 WHERE t2.id=tl.temp2_id AND   t2.active_tag=1 )

答案 1 :(得分:1)

加入"已完成"按照ON条款的顺序排列。联接不仅仅在表之间 - 它们经常在其他联接产生的结果之间。所以:

select * from #temp t
left join #table_link tl on tl.temp_id=t.id
inner join  #temp2 t2 on t2.id=tl.temp2_id and t2.active_tag=1

首先在left joint之间执行tl。这会生成一个新结果集(我们称之为ttl),其中包含来自t的行,而可能包含来自tlnull s的联接行(因为它是left join)。我们然后将结果ttl加入t2,执行内部联接。但是,我们知道ttl可能包含来自null的列的tl,因此inner join将失败。

我们可以写的是:

select * from #temp t
left join #table_link tl
inner join #temp2 t2
 on t2.id=tl.temp2_id and t2.active_tag=1
 on tl.temp_id=t.id

请注意,我现在(通过移动on子句)更改了联接的顺序。我们现在首先inner jointl之间执行t2(让我们称之为t2tl)和然后left joint之间执行t2tl。这意味着left join行为持续,因此我们可以再次获得null结果。

要了解联接和on条款的行为,请将join一词视为(,将on条款视为)。然后,您会发现on子句与查找匹配() s所涉及的联接。

答案 2 :(得分:0)

试试这个:

 SELECT * 
 FROM #temp
 LEFT JOIN #table_link ON #table_link.id = #temp.id
 LEFT JOIN #temp2 ON #table_link.temp_id = #temp2.id

您将获得所需的输出。您的查询中的问题可能是因为加入了以下#temp2:   t2.id=tl.temp2_id