SQL 到 return 父行,即使没有子行

SQL to return parent rows even when no child rows

我有一组 table。当我过滤第二个 table、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

正如其他人所提到的,您可以将 t3 过滤器移出整个 WHERE 子句并将其放入 JOIN,这可以防止它有效地将您的外部连接转变为伪内部连接加入(发生这种情况是因为 NULL 值中的 none 可以匹配 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

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

SELECT *
FROM   table1 A
       LEFT JOIN table2 B
              ON A.id = B.relatedid  

您可以简单地使用左连接:

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

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

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

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

为避免这种情况,请将您的条件放入联接中,如下所示:

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

或将 IsNull 添加到您的 where 子句中,如下所示:

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

编辑:现在您已经发布了您的查询,这里是一个具体的答案:只需将 "where" 更改为 "and,",它将 return 您指定的结果。

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'