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'
- 正在编辑我的问题 *
我有一组 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'