请考虑以下SQL。
declare @t1 table(site int, id int, name varchar(2))
declare @t2 table(site int, id int, mark int)
insert into @t1
select 1,1,'A'
union select 1,2,'B'
union select 1,3,'C'
union select 2,2,'D'
union select 2,3,'C'
insert into @t2
select 1,1,10
union select 1,2,20
union select 0,3,30
union select 1,3,40
union select 2,3,40
union select 2,3,40
select distinct a.site, a.id,a.name,b.mark
from @t1 a
inner join @t2 b
on (a.site =b.site or b.site = 0) and a.id = b.id
where a.site=1
它产生以下结果
site id name mark ---------------------------- 1 1 A 10 1 2 B 20 1 3 C 30 1 3 C 40
没错。
但我想要一个人的数据一次。 SQL应首先检查@ t2中是否有针对特定站点的人员条目。如果找到了条目,则使用它。如果没有,该人的标记将是在网站0中具有相同名称的人的标记。
在这种情况下,我想要的结果如下。
site id name mark ---------------------------- 1 1 A 10 1 2 B 20 1 3 C 40
但如果(1,3,40)不在@ t2中,结果应如下所示。
site id name mark ---------------------------- 1 1 A 10 1 2 B 20 1 3 C 30
我该怎么做? 我可以使用Common Table Expression来完成它。 所以请给我一个更快的方法。 我将在大约1亿行上运行它。
答案 0 :(得分:0)
外部加入t2表两次,并使用子查询确保只包含匹配或为零的记录。
Select distinct a.site, a.id, a.name,
coalesce(sm.mark, zs.mark) mark
from @t1 a
Left Join @t2 sm -- for site match
on sm.id = a.id
And sm.site = a.site
Left Join @t2 zs -- for zero site
on zs.id = a.id
And zs.site = 0
Where Exists (Select * From @t2
Where id = a.id
And Site In (a.Site, 0))
And a.site=1
答案 1 :(得分:0)
您可以将所有条件转换为on
子句:
declare @target_site as Int = 1
select distinct a.site, a.id, a.name, b.mark
from @t1 as a inner join
@t2 as b on a.site = @target_site and a.id = b.id and
( a.site = b.site or ( b.site = 0 and not exists ( select 42 from @t2 where site = @target_site and id = a.id ) ) )