Home > Back-end >  PostgreSQL users and balances - use previous balance for user in time series if value is missing
PostgreSQL users and balances - use previous balance for user in time series if value is missing

Time:10-12

Given the following tables:

users:

name
alice
bob

balances:

id user_name date balance
1 alice 2022-01-01 100
2 alice 2022-01-03 200
3 alice 2022-01-04 300
4 bob 2022-01-01 400
5 bob 2022-01-02 500
6 bob 2022-01-05 600

I would like to get a full list of all days from the first available to the last for all users, replacing NULL balances with the last available balance for that user.

This is what I have so far:

select u.name, s.day, b.balance
from users u
cross join (select generate_series(min(day)::date, max(day)::date, interval '1 day')::date as day from balances) s
left join balances b on b.user_name = u.name and s.day = b.day
order by u.name, s.day 
;

SQL Fiddle Here

I have tried LAG() and some other examples found here but none of them seem to get the right last balance for the user.

CodePudding user response:

We want to use running_total: sum() over()

select      u.name
           ,s.day
           ,sum(b.balance) over(partition by u.name order by s.day) as balance
from        users u
cross join (select generate_series(min(day)::date, max(day)::date, interval '1 day')::date as day from balances) s
left join   balances b on b.user_name = u.name and s.day = b.day
order by    u.name, s.day 
name day balance
alice 2022-01-01 100
alice 2022-01-02 100
alice 2022-01-03 300
alice 2022-01-04 600
alice 2022-01-05 600
bob 2022-01-01 400
bob 2022-01-02 900
bob 2022-01-03 900
bob 2022-01-04 900
bob 2022-01-05 1500

Fiddle

  • Related