2
  • 编辑我的问题 *

我有一组桌子。当我对第二个表 t2 进行过滤时,我仍然希望获得 t1 的所有行。

SQL脚本如下。我觉得我在修补时越来越近了,但我就是做不到。

简而言之,我需要 t2 的行(如果适用),但 t1 的所有行在其他列中都带有空值。

谢谢。

创建表 t1 ( id int identity(1,1), parentName varchar(20) null )
创建表 t2 ( id int identity(1,1), t1id int not null, childName varchar(20) null )
创建表 t3 ( id int identity(1,1), t2id int not null, gChildName varchar(20) null )

插入 t1 ( parentName ) 值 ( 'bob' )
插入 t1 ( parentName ) 值 ( 'john' )

插入 t2 ( childName, t1id ) 值 ( 'irving', 1 )
插入 t2 ( childName, t1id ) 值 ( 'parna', 1 )
插入 t2 ( childName, t1id ) 值 ( 'mike', 1 )

选择
      t1.id,
      t1.parentName,
      t2.id,
      t2.childName
从 t1 左外连接 t2
      在 t2.t1id = t1.id
其中 t2.childName = 'mike'

-- 我想要的是:
-- 1,鲍勃,3,迈克
-- 2,约翰,空,空

删除表 t3
删除表 t2
删除表 t1
4

4 回答 4

4

正如其他人所提到的,您可以将 t3 过滤器移出整个WHERE子句并将其放入JOIN,这可以防止它有效地将您的外部联接变成伪内部联接(发生这种情况是因为没有任何NULL值可以匹配WHERE标准,除了对于IS NULL)

这是对您的示例代码的一个非常简单的更改 - 只需更改WHEREAND.

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
于 2015-04-23T19:27:34.817 回答
2

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

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

将删除表 1 中表 2 中没有匹配项的所有行,即使您离开连接(因为当 b.name 为空时不满足 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%'

编辑:既然您已经发布了查询,这里有一个具体的答案:只需将“where”更改为“and”,它将返回您指定的结果。

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'
于 2015-04-23T19:37:09.710 回答
0

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

从表 1 A 中选择 *

在 A.ID=B.RELATEDID 上左连接表 2 B

于 2015-04-23T19:28:23.460 回答
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
于 2015-04-23T19:32:44.390 回答