SQL Server - 为where子句条件提供优先级

时间:2012-12-13 15:55:35

标签: sql sql-server-2008

请考虑以下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亿行上运行它。

2 个答案:

答案 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 ) ) )