同一 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
我正在查询一个数据仓库(所以我无法重新设计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