Reputation: 21
I have created the following table:
create table AccountBalances (
Year varchar(255),
Period varchar(255),
Account numeric,
Amount numeric
)
Insert into AccountBalances(Year, Period, Account, Amount)
Values ('2014', '1', '1210', '100'),
('2014', '1', '1210', '200'),
('2014', '3', '1210', '100')
Now I want to calculate the running total for each period per account. However may main issue is calculating running totals for periods without transactions. I want my result like this:
Year Period Account Amount
2014 1 1210 300
2014 2 1210 300
2014 3 1210 400
From the transaction table period 2 is not present, but I want to calculate the running total for this period in my running total table.
Upvotes: 2
Views: 9090
Reputation: 19
Another approach would be to use a separate Period_lookup table having all possible periods (Months) for a year.
Then we could do an outer join and apply the IsNull / Coalesce function in the select to return the desired results.
Upvotes: 0
Reputation: 438
A system-neutral (works on all database systems and versions) and widely used approach to problems like this, is to maintain a Date
table containing one row for every day of every year that your application or analysis is interested in.
I believe some database systems can generate something like this on-the-fly, but a stored table takes up very minimal space (365 or 366 rows per year - nothing to a relational database) and can be used in a huge variety of situations. Populate it once for a long number of years into the future and it will serve you well.
For your particular case, you'd want this Date
table to include both Year
and Period
columns: you need to determine how periods are defined, e.g. is that the same as a month or something else like 4-week chunks of time?
Then you can do a query along these lines (please treat as pseudocode - your exact requirements may vary):
with cteAllPeriods as (
select distinct
Year
,Period
from Date
where Year >= 2014 -- Whatever suitable restrictions here
)
select D.Year
,D.Period
,AB.Account
,sum(AB.Amount)
from cteAllPeriods D
-- Assuming this is a running total
-- from the start of the calendar year
left join AccountBalances AB on D.Year=AB.Year
and D.Period>=AB.Period -- Gets everything UP TO the current period
group by D.Year
,D.Period
,AB.Account
Upvotes: 2
Reputation: 432261
From SQL Server 2012 onwards you can do this
SELECT
*,
SUM(Amount) OVER (PARTITION BY Year, Account ORDER BY Period RANGE UNBOUNDED PRECEDING)
FROM
AccountBalances
Upvotes: 2