如何在SQL 2014中获取组的运行小计金额?
我有一张包含交易金额的表格。我需要总结一下,为每个项目和季度找到有数据的行,并且需要在每个项目中运行一个小计。对于每个新项目,运行总计需要重置为零。
这是我到目前为止所做的:
SELECT [ProjectId]
, SUM( ActualAmount) AS PeriodAmount
, SUM( ActualAmount) OVER (PARTITION BY ProjectId ORDER BY ProjectId,YearQuarter)
AS FairMarketValue
FROM GLSnapshot
GROUP BY [ProjectId] , [YearQuarter]
我目前收到此错误:
Msg 8120,Level 16,State 1,Line 3
Column 'GLSnapshot.ActualAmount' is invalid in the
select list because it is not contained in either an
aggregate function or the GROUP BY clause.
示例数据:假设我有表格GLSnapshot的以下数据:
ProjectId, YearQuarter, ActualAmount
'A', '2015Q1' , 9000.00
'A', '2015Q1' , 100.00
'A', '2015Q2' , 50.00
'A', '2015Q3' , 50.00
'A', '2015Q3' , 200.00
'B', '2015Q1' ,80000.00
我应该得到
的以下结果ProjectId, YearQuarter, PeriodAmount, FairMarketValue (Running Subtotal):
'A', '2015Q1' , 9100.00 , 9100.00
'A', '2015Q2' , 50.00 , 9150.00
'A', '2015Q3' , 250.00 , 9400.00
'B', '2015Q1' ,80000.00 , 80000.00
答案 0 :(得分:2)
OLAP功能在汇总后计算,您无法使用ActualAmount
,必须为SUM( ActualAmount)
。并且无需按ProjectId
订购,因为它已在PARTITION BY
中。最后使用ROWS UNBOUNDED PRECEDING
,否则默认为RANGE UNBOUNDED PRECEDING
,这更昂贵,可能无法返回预期结果:
SELECT [ProjectId]
, [YearQuarter]
, SUM( ActualAmount) AS PeriodAmount
, SUM( SUM( ActualAmount))
OVER (PARTITION BY ProjectId
ORDER BY YearQuarter
ROWS UNBOUNDED PRECEDING) AS FairMarketValue
FROM GLSnapshot
GROUP BY [ProjectId] , [YearQuarter]
答案 1 :(得分:0)
您可以使用之前无界限的行来提供总计
;with cte as (
select ProjectID, YearQuarter, ActualAmount
from GLSnapshot
) , cte2 as (
select ProjectID, YearQuarter, sum(ActualAmount) SumActualAmount from cte Group by ProjectID, YearQuarter
) Select *, sum(SumActualAmount) over(partition by projectid order by projectid, yearquarter rows unbounded preceding) as RunningTotal from cte2
答案 2 :(得分:0)
试试这个:
CREATE TABLE #GLSnapshot (ProjectId VARCHAR(5), YearQuarter VARCHAR(6), ActualAmount NUMERIC(18,2))
INSERT INTO #GLSnapshot
SELECT 'A', '2015Q1' , 9000.00 UNION ALL
SELECT 'A', '2015Q1' , 100.00 UNION ALL
SELECT 'A', '2015Q2' , 50.00 UNION ALL
SELECT 'A', '2015Q3' , 50.00 UNION ALL
SELECT 'A', '2015Q3' , 200.00 UNION ALL
SELECT 'B', '2015Q1' ,80000.00
;WITH T
AS
(
SELECT ROW_NUMBER() over(partition by ProjectId ORDER by YearQuarter) RN,
ProjectId,YearQuarter,sum(ActualAmount) PeriodAmount
FROM #GLSnapshot
GROUP BY ProjectId,YearQuarter
)
SELECT T1.ProjectId,T1.YearQuarter,T1.PeriodAmount, SUM(T2.PeriodAmount) FairMarketValue
FROM T T1
INNER JOIN T T2 ON T1.ProjectId = T2.ProjectId and T1.RN >= T2.RN
GROUP BY T1.ProjectId,T1.YearQuarter,T1.PeriodAmount
答案 3 :(得分:0)
您可以使用ROWS UNBOUNDED PRECEDING
尝试此查询;with cte as (
select ProjectID, YearQuarter, ActualAmount
from GLSnapshot
) , cte2 as (
select ProjectID, YearQuarter, sum(ActualAmount) SumActualAmount from cte Group by ProjectID, YearQuarter
) Select *, sum(SumActualAmount) over(partition by projectid order by projectid, yearquarter rows unbounded preceding) as RunningTotal from cte2