我正在查询数据仓库(因此我无法重新设计表格),我将尽力在一个简单的示例中模仿场景。
我们有3个主要的事件,更改和发布表。这3个通过称为中间的中间表连接。以下是它们的结构以及样本数据:
事件表:
更改表格
发布表:
中级表:
前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
此查询提供了我所需的结果:
但我认为我处理这个查询的方式是如此幼稚而且效率不高。我的数据仓库可能在中间表中包含大约数百万条记录,而我的方法可能太慢。
问题: 有没有更好的方法来获得更好的性能?
BTW,我正在使用MS SQL Server 2012
答案 0 :(得分: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
答案 1 :(得分: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