1

请考虑以下 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

它产生以下结果

站点 ID 名称 标记
----------------------------
1 1 10
1 2 乙 20
1 3 C 30
1 3 C 40

这是正确的。

但我只想要一个人的数据一次。SQL 应首先检查特定站点的@t2 中是否存在人员条目。如果找到条目,则使用它。如果不是,则该人的标记将是站点 0 中具有相同名称的人的标记。

在这种情况下,我想要的结果如下。

站点 ID 名称 标记
----------------------------
1 1 10
1 2 乙 20
1 3 C 40

但是如果 (1,3,40) 不在@t2 中,结果应该如下。

站点 ID 名称 标记
----------------------------
1 1 10
1 2 乙 20
1 3 C 30

我怎样才能做到这一点?我可以使用公用表表达式来做到这一点。所以请给我一个更快的方法。我将在大约 1 亿行上运行它。

4

2 回答 2

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
于 2012-12-13T16:22:26.317 回答
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 ) ) )
于 2012-12-13T16:49:38.973 回答