SQL即使没有子行也返回父行

时间:2015-04-23 19:22:41

标签: sql sql-server select ansi-nulls

  • 编辑我的问题*

我有一组表格。当我在第二个表格t2上过滤时,我仍然希望得到t1的所有行。

SQL脚本如下。我觉得自己在修补时变得越来越近,但我无法实现它。

简而言之,我在需要时需要t2的行,但在其他列中需要t1的所有行。

感谢。

create table t1 ( id int identity(1,1), parentName varchar(20) null )
create table t2 ( id int identity(1,1), t1id int not null, childName varchar(20) null )
create table t3 ( id int identity(1,1), t2id int not null, gChildName varchar(20) null )

insert into t1 ( parentName ) values ( 'bob' )
insert into t1 ( parentName ) values ( 'john' )

insert into t2 ( childName, t1id ) values ( 'irving', 1 )
insert into t2 ( childName, t1id ) values ( 'parna', 1 )
insert into t2 ( childName, t1id ) values ( 'mike', 1 )

select
      t1.id,
      t1.parentName,
      t2.id,
      t2.childName
from t1 left outer join t2
      on t2.t1id = t1.id
where t2.childName = 'mike'

-- what i'd LIKE is:
-- 1, bob, 3, mike
-- 2, john, null, null

drop table t3
drop table t2
drop table t1

4 个答案:

答案 0 :(得分:4)

正如其他人所提到的,你可以将t3过滤器移出整个WHERE子句并将其放入JOIN,这可以防止它有效地将你的外连接转换为伪内连接(之所以会发生这种情况,是因为除了NULL之外,WHERE值都不能与IS NULL条件相匹配

对您的示例代码进行非常直接的更改 - 只需将WHERE更改为AND

create table t1 ( id int identity(1,1), parentName varchar(20) null )
create table t2 ( id int identity(1,1), t1id int not null, childName varchar(20) null )
create table t3 ( id int identity(1,1), t2id int not null, gChildName varchar(20) null )

insert into t1 ( parentName ) values ( 'bob' )
insert into t1 ( parentName ) values ( 'john' )

insert into t2 ( childName, t1id ) values ( 'irving', 1 )
insert into t2 ( childName, t1id ) values ( 'parna', 1 )
insert into t2 ( childName, t1id ) values ( 'mike', 1 )

select
  t1.id,
  t1.parentName,
  t2.id,
  t2.childName

from t1
  left outer join t2 on t2.t1id = t1.id and t2.childName = 'mike'

drop table t3
drop table t2
drop table t1

答案 1 :(得分:2)

听起来您可能正在使用左连接,但随后根据您的where子句删除行。例如:

Select * from Table1 a
left join Table2 b
on a.ID = b.ID
where b.name like 'A%'

将删除表1中表2中没有匹配项的所有行,即使您已离开连接(因为当b.name为null时,不满足where条件)。

为避免这种情况,请将条件放在连接中,如下所示:

Select * from Table1 a
left join Table2 b
on a.ID = b.ID and b.name like 'A&'

或在你的where子句中添加一个IsNull,如下所示:

Select * from Table1 a
left join Table2 b
on a.ID = b.ID
where ISNULL(b.name, 'A') like 'A%'

编辑:现在您已经发布了查询,这是一个具体的答案:只需更改"其中"到"和,"它将返回您指定的结果。

select
  t1.id,
  t1.parentName,
  t2.id,
  t2.childName
from #t1 t1 left outer join #t2 t2
  on t2.t1id = t1.id 
  and t2.childName = 'mike'

答案 2 :(得分:0)

如果要加入2个或更多表,并希望得到第一个表的结果,即使第二个(或第三个等)没有匹配,您只需要将连接更改为左连接。像

这样的东西

SELECT * FROM TABLE1 A

LEFT JOIN TABLE2 B ON A.ID = B.RELATEDID

答案 3 :(得分:0)

您只需使用左连接:

Select t1.id,t1.name,t2.id id2,t2.name name2,t3.id id3,t3.name name3
From t1 left join
     t2 on t1.id=t2.t1id left join
     t3 on t3.t2id=t2.id
Where your condition here