2015-10-14 121 views
1

我在查詢數據倉庫(所以我不能重新設計表),我會盡我所能在一個簡單的示例中模擬這種情況。同一表中兩列的總和

我們有3個主要的事件,更改和發佈表。這3個通過稱爲中間的中間表連接。這裏是它們的結構與樣本數據一起:

事件表:

enter image description here

變化表:

enter image description here

釋放臺:

enter image description here

中間表:

enter image description here

前3代表具有完全相同的結構,但是中間表保存這些3個表成對的連接。例如,如果Rel1連接到Chg1,則在中間表中有一行爲或。這兩行沒有區別,可能不共存。

QUERY:

我希望所有版本的記錄與相關事件的數量和相關的變更號碼。這是我如何實現這一點:

WITH SourceTable AS(
SELECT R.ReleaseItem, R.Prop1, R.Prop2 , I.RelOrInc2 as [RelatedIncident] , Null as [RelatedChanges] FROM Release R 
    LEFT JOIN [Intermediate] I 
    ON R.ReleaseItem = I.RelOrInc1 
    WHERE SUBSTRING(I.RelOrInc2,1,3) = 'Inc' 
UNION 

SELECT R.ReleaseItem, R.Prop1, R.Prop2 , I.RelOrInc1 , Null as [RelatedChanges] FROM Release R 
    LEFT JOIN [Intermediate] I 
    ON R.ReleaseItem = I.RelOrInc2 
    WHERE SUBSTRING(I.RelOrInc1,1,3) = 'Inc' 

UNION 

SELECT R.ReleaseItem, R.Prop1, R.Prop2 , Null as [RelatedIncident] , I.RelOrInc2 as [RelatedChanges] FROM Release R 
    LEFT JOIN [Intermediate] I 
    ON R.ReleaseItem = I.RelOrInc1 
    WHERE SUBSTRING(I.RelOrInc2,1,3) = 'Chg' 
UNION 

SELECT R.ReleaseItem, R.Prop1, R.Prop2 , Null as [RelatedIncident] , I.RelOrInc1 as [RelatedChanges] FROM Release R 
    LEFT JOIN [Intermediate] I 
    ON R.ReleaseItem = I.RelOrInc2 
    WHERE SUBSTRING(I.RelOrInc1,1,3) = 'Chg' 
    ) 

SELECT REL.* , COUNT(S.RelatedIncident) As [No Of Related Incidents] , COUNT(S.[RelatedChanges]) AS [No of Related Changes] FROM Release REL 
    LEFT JOIN SourceTable S 
    ON REL.ReleaseItem = S.ReleaseItem 
GROUP BY REL.ReleaseItem, REL.Prop1, REL.Prop2 

該查詢給我我需要的結果:

enter image description here

但我覺得我處理這個查詢的方式是那麼的幼稚和效率不高。我的數據倉庫可能包含數百萬中間表中的記錄,我的方法可能太慢。

問題: 有沒有更好的方法來獲得更好的性能這樣的結果?

順便說一句,我正在使用MS SQL Server 2012

回答

2
SELECT 
    R.ReleaseItem, R.Prop1, R.Prop2, 
    [No Of Related Incidents] = (SELECT COUNT(*) FROM [Intermediate] i 
     WHERE (i.RelOrInc1 = r.ReleaseItem AND i.RelOrInc2 LIKE 'Inc%') 
     OR (i.RelOrInc2 = r.ReleaseItem AND i.RelOrInc1 LIKE 'Inc%')), 
    [No of Related Changes] = (SELECT COUNT(*) FROM [Intermediate] i 
     WHERE (i.RelOrInc1 = r.ReleaseItem AND i.RelOrInc2 LIKE 'Chg%') 
     OR (i.RelOrInc2 = r.ReleaseItem AND i.RelOrInc1 LIKE 'Chg%')) 
FROM Release R 
+0

這個表示法適用於所有版本的MS SQL Server,我的意思是[列別名] =(某個查詢)。您的查詢非常簡潔明瞭。謝謝 –

+0

@YasserSobhdel,很高興提供幫助。是的,它支持所有版本的SQL Server,至少SQL Server 2005及更高版本。 – EricZ

1

我認爲這將適用於你。不能說任何有關性能的事情。你應該檢查。

select r.releaseitem, 
     r.prop1, 
     r.prop2, 
     sum(case when t.relorinc2 like 'inc%' then 1 else 0 end) as incidents, 
     sum(case when t.relorinc2 like 'chg%' then 1 else 0 end) as changes  
from (select relorinc1, relorinc2 from intermediate where relorinc1 like 'rel%' 
     union all 
     select relorinc2, relorinc1 from intermediate where relorinc2 like 'rel%')t 
join release r on t.relorinc1 = r.releaseitem 
group by r.releaseitem, r.prop1, r.prop2 
+0

謝謝你,我想其他職位更簡單,因此我標誌着作爲答案。 –