2012-12-13 39 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

非常感謝。但是仍然懷疑子查詢的性能。 –