Reputation: 2827
I have seen rolling 12's on averages and counts, but not on a sum.
I have a table like so
ID | Profile_ID | EntryLocation | EntryMonth | Usage
-----------------------------------------------------------
1 | 1 | 11 | 2019-06-01 | 60.00
2 | 1 | 12 | 2019-05-01 | 40.00
3 | 1 | 11 | 2019-05-01 | 30.00
4 | 2 | 11 | 2019-06-01 | 100.00
5 | 1 | 12 | 2019-06-01 | 74.00
6 | 2 | 12 | 2019-06-01 | 456.00
7 | 2 | 11 | 2019-05-01 | 33.00
8 | 1 | 11 | 2019-07-01 | 200.00
9 | 1 | 11 | 2018-06-01 | 100.00
And what I want to do is sum up the usage all the previous months, grouping on Profile_ID
,EntryLocation
, and EntryMonth
(which make up a clustered primary key (i.e. the combination of the three is unique).
So the result I am looking for would be the following:
ID | Profile_ID | EntryLocation | EntryMonth | Rolling12Usage
-----------------------------------------------------------
1 | 1 | 11 | 2018-06-01 | 100.00
2 | 1 | 11 | 2019-05-01 | 130.00 --> (100 + 30)
3 | 1 | 11 | 2019-06-01 | 90.00 -->(30 + 60 (note the 100 fell off))
4 | 1 | 11 | 2019-07-01 | 290.00 -->(90 + 200)
5 | 1 | 12 | 2019-05-01 | 40.00
6 | 1 | 12 | 2019-06-01 | 114.00 -->(40 + 74)
7 | 2 | 11 | 2019-05-01 | 33.00
8 | 2 | 11 | 2019-06-01 | 133.00 -->(33 + 100)
9 | 2 | 12 | 2019-06-01 | 456.00
I have tried this with grouping
select x.Profile_ID, x.EntryLocation, x.EntryMonth, sum(Usage) as [SumUsage],
(sum(sum(Usage)) over (order by x.EntryMonth rows between 11 preceding and current row)
) as Sum_12month
from my_table_with_values x
group by x.EntryMonth, x.Profile_ID, x.EntryLocation
order by x.EntryMonth
But couldn't get the ordering right. Any ideas/help?
Bonus points if you want to add the solution for doing it WITHOUT assuming a clustered primary key on those values (I bet that situation may be more/as common as mine).
Upvotes: 1
Views: 186
Reputation: 1269793
I think you need a partition by
:
select x.Profile_ID, x.EntryLocation, x.EntryMonth, sum(Usage) as [SumUsage],
sum(sum(Usage)) over (partition by Profile_ID, EntryLocation
order by x.EntryMonth
rows between 11 preceding and current row
) as Sum_12month
from my_table_with_values x
group by x.EntryMonth, x.Profile_ID, x.EntryLocation
order by x.EntryMonth;
If you don't have all months, you can use range
instead of rows
:
select x.Profile_ID, x.EntryLocation, x.EntryMonth, sum(Usage) as [SumUsage],
sum(sum(Usage)) over (partition by Profile_ID, EntryLocation
order by x.EntryMonth
range between interval 11 month preceding and current row
) as Sum_12month
from my_table_with_values x
group by x.EntryMonth, x.Profile_ID, x.EntryLocation
order by x.EntryMonth;
Upvotes: 1
Reputation: 3791
Is this what you are looking for?
SELECT x.Profile_ID,
x.EntryLocation,
x.Entry_Month,
SUM(x2.Usage)
FROM my_table_with_values x
LEFT
JOIN my_table_with_values x2
ON x.Profile_id = x2.Profile_id
AND x.Entry_Location x2.Entry_Location
AND x2.Entry_Month BETWEEN DATEADD(month, -11, x.entrymonth)
And x.entrymonth
GROUP
BY x.Profile_ID,
x.EntryLocation,
x.Entry_Month
Upvotes: 1