繁体   English   中英

左连接条件

[英]Left join with condition

假设我有这些表

create table bug (
    id int primary key, 
    name varchar(20)
)
create table blocking (
    pk int primary key,
    id int, 
    name varchar(20)
)

insert into bug values (1, 'bad name')
insert into bug values (2, 'bad condition')
insert into bug values (3, 'about box')
insert into blocking values (0, 1, 'qa bug')
insert into blocking values (1, 1, 'doc bug')
insert into blocking values (2, 2, 'doc bug')

我想加入id列的表格,结果应该是这样的:

id          name                 blockingName
----------- -------------------- --------------------
1           bad name             qa bug
2           bad condition        NULL
3           about box            NULL

这意味着:我想从#bug返回所有行,'blockingName'列中应该只有'qa bug'值或NULL(如果找不到#blocking中的匹配行)


我天真的选择是这样的:

select * from #bug t1 
    left join #blocking t2 on t1.id = t2.id
    where t2.name is null or t2.name = 'qa bug'

但这不起作用,因为似乎条件首先应用于#blocking表然后它被连接。

这个问题的最简单/典型解决方案是什么? (我有一个嵌套选择的解决方案,但我希望有更好的东西)

简单地在加入中加入“qa bug”标准:

select t1.*, t2.name from #bug t1 
left join #blocking t2 on t1.id = t2.id AND t2.name = 'qa bug'

正确的选择是:

create table bug (
id int primary key, 
name varchar(20)
)
insert into bug values (1, 'bad name')
insert into bug values (2, 'bad condition')
insert into bug values (3, 'about box')

CREATE TABLE blocking
(
pk int IDENTITY(1,1)PRIMARY KEY ,
id int, 
name varchar(20)
)
insert into blocking values (1, 'qa bug')
insert into blocking values (1, 'doc bug')
insert into blocking values (2, 'doc bug')


select 
t1.id, t1.name,
(select  b.name from blocking b where b.id=t1.id and b.name='qa bug')
from bug t1 

看起来您只想从#blocking选择一行并将其加入#bug 我会做:

select t1.id, t1.name, t2.name as `blockingName` 
from `#bug` t1
left join (select * from `#blocking` where name = "qa bug") t2
on t1.id = t2.id
select * 
from #bug t1 
left join #blocking t2 on t1.id = t2.id and t2.name = 'qa bug'

确保内部查询仅返回一行。 如果返回多个,则可能必须在其上添加前1。

select 
t1.id, t1.name,
(select  b.name from #blocking b where b.id=t1.id and b.name='qa bug')
from #bug t1 

这是一个演示: http//sqlfiddle.com/#!2/414e6/1

select
  bug.id,
  bug.name,
  blocking.name as blockingType
from
  bug
    left outer join blocking on
      bug.id = blocking.id AND
      blocking.name = 'qa bug'
order by
  bug.id

通过在左外连接下添加“blocking.name”子句而不是where,您指示它也应该被视为“外部”或可选。 当where子句的一部分时,它被认为是必需的(这就是过滤掉空值的原因)。

BTW - sqlfiddle.com是我的网站。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM