Performing cumulative calculations in SQL
summary
The cumulative value of the amount in year-month units is calculated using SQL.
Operation check version
Supported SQL Server Versions
- 2005
- 2008
- 2008 R2
Check SQL Server Version
- 2005
- 2008
- 2008 R2
Tested Windows version
- 2008
- 2008 R2
substance
Normally, when using a database, the amount of money is often calculated for the specified year and month, but there are also cases where the amount of this month is added based on the data of the previous month such as amount and inventory. You can calculate cumulative values stored or programmatically, but for now I want to do the calculation only in SQL.
There is a table below, with amounts set for each year and month:
Year-Month | Amount | Cumulative | Year-Unit Amount Cumulative |
---|---|---|---|
201004 | 100 | null | null |
201005 | 200 | null | null |
201006 | 150 | null | null |
201007 | 300 | null | null |
201008 | 50 | null | null |
201009 | 220 | null | null |
201010 | 240 | null | null |
201011 | 280 | null | null |
201012 | 400 | null | null |
201101 | 450 | null | null |
201102 | 520 | null | null |
201103 | 120 | null | null |
201104 | 140 | null | null |
201105 | 450 | null | null |
201106 | 270 | null | null |
201107 | 640 | null | null |
201108 | 340 | null | null |
201109 | 230 | null | null |
201110 | 280 | null | null |
201111 | 320 | null | null |
201112 | 350 | null | null |
201201 | 230 | null | null |
201202 | 270 | null | null |
201203 | 350 | null | null |
In order to update in a batch in SQL, instead of using "the amount of the previous month" as "the amount of the previous month", you can calculate the cumulative value by attaching the condition that the past amount is aggregated from the target year and the month.
update 金額集計Test
set 金額累計 = 累計
from
(
select
A.年月,
sum(B.金額) as 累計
from 金額集計Test A
left outer join 金額集計Test B
on B.年月 <= A.年月
group by A.年月
) as C
where 金額集計Test.年月 = C.年月
When you execute the above SQL, the cumulative value is entered in "Amount Cumulative".
Year-Month | Amount | Cumulative | Year-Unit Amount Cumulative |
---|---|---|---|
201004 | 100 | 100 | null |
201005 | 200 | 300 | null |
201006 | 150 | 450 | null |
201007 | 300 | 750 | null |
201008 | 50 | 800 | null |
201009 | 220 | 1020 | null |
201010 | 240 | 1260 | null |
201011 | 280 | 1540 | null |
201012 | 400 | 1940 | null |
201101 | 450 | 2390 | null |
201102 | 520 | 2910 | null |
201103 | 120 | 3030 | null |
201104 | 140 | 3170 | null |
201105 | 450 | 3620 | null |
201106 | 270 | 3890 | null |
201107 | 640 | 4530 | null |
201108 | 340 | 4870 | null |
201109 | 230 | 5100 | null |
201110 | 280 | 5380 | null |
201111 | 320 | 5700 | null |
201112 | 350 | 6050 | null |
201201 | 230 | 6280 | null |
201202 | 270 | 6550 | null |
201203 | 350 | 6900 | null |
In addition, if you want to reset the cumulative value every year, you can calculate it by changing the conditional expression.
update 金額集計Test
set 年度単位金額累計 = 累計
from
(
select
A.年月,
sum(B.金額) as 累計
from 金額集計Test A
left outer join 金額集計Test B
on B.年月 <= A.年月
and B.年月 >= case
when cast(right(A.年月, 2) as int) >= 4 then left(A.年月, 4) + N'04'
else cast(cast(left(A.年月, 4) as int) - 1 as nvarchar(4)) + N'04'
end
group by A.年月
) as C
where 金額集計Test.年月 = C.年月
When you execute the above SQL, the cumulative value is entered in "Annual Amount Cumulative".
Year-Month | Amount | Cumulative | Year-Unit Amount Cumulative |
---|---|---|---|
201004 | 100 | 100 | 100 |
201005 | 200 | 300 | 300 |
201006 | 150 | 450 | 450 |
201007 | 300 | 750 | 750 |
201008 | 50 | 800 | 800 |
201009 | 220 | 1020 | 1020 |
201010 | 240 | 1260 | 1260 |
201011 | 280 | 1540 | 1540 |
201012 | 400 | 1940 | 1940 |
201101 | 450 | 2390 | 2390 |
201102 | 520 | 2910 | 2910 |
201103 | 120 | 3030 | 3030 |
201104 | 140 | 3170 | 140 |
201105 | 450 | 3620 | 590 |
201106 | 270 | 3890 | 860 |
201107 | 640 | 4530 | 1500 |
201108 | 340 | 4870 | 1840 |
201109 | 230 | 5100 | 2070 |
201110 | 280 | 5380 | 2350 |
201111 | 320 | 5700 | 2670 |
201112 | 350 | 6050 | 3020 |
201201 | 230 | 6280 | 3250 |
201202 | 270 | 6550 | 3520 |
201203 | 350 | 6900 | 3870 |