我有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 |
请解释为什么它不起作用?
答案 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 join
和t
之间执行tl
。这会生成一个新结果集(我们称之为ttl
),其中包含来自t
的行,而可能包含来自tl
或null
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 join
和tl
之间执行t2
(让我们称之为t2tl
)和然后在left join
和t
之间执行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