2012-12-13 19 views
1

请考虑以下SQL。SQL Server - 提供where子句条件的优先级

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

您可以滚动的所有条件进入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))) 
+0

非常感谢。但是仍然怀疑子查询的性能。 –

+0

@JakirHossain - 包含'site'和'id'的'@ t2'上是否有索引? – HABO

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 
+0

非常感谢。但是仍然怀疑子查询的性能。 –