同一 table 中两列的总和

Aggregate sum on two columns in the same table

我正在查询一个数据仓库(所以我无法重新设计tables),我会尽力在一个简单的例子中模拟场景。

我们有 3 个主要 table 事件、变更和发布。这 3 个通过称为中间体的中间体 table 连接。这是它们的结构以及示例数据:

事件Table:

更改Table:

发布Table:

中级 Table:

前 3 个 table 具有完全相同的结构,但中间 table 保持这 3 个 table 成对的连接。例如,如果 Rel1 连接到 Chg1,则中间有一行 table 为 or 。这两行没有区别,不能共存。

查询:

我想要所有发布记录以及相关事件的数量和相关更改的数量。以下是我如何实现的:

 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

这个查询给出了我需要的结果:

但我认为我处理此查询的方式非常幼稚且效率低下。我的数据仓库可能包含大约数百万条中间记录table,我的方法可能太慢了。

问题: 有没有更好的方法以更好的性能获得这样的结果?

顺便说一句,我正在使用 MS SQL Server 2012

我认为这对你有用。不能说什么性能。你应该检查一下。

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