Sample Header Ad - 728x90

Generate a series of dates for each group in a table

9 votes
2 answers
18867 views
I have a balances table in PostgreSQL 9.3 that looks like this: ~~~pgsql CREATE TABLE balances ( user_id INT , balance INT , as_of_date DATE ); INSERT INTO balances (user_id, balance, as_of_date) VALUES (1, 100, '2016-01-03') , (1, 50, '2016-01-02') , (1, 10, '2016-01-01') , (2, 200, '2016-01-01') , (3, 30, '2016-01-03') ; ~~~ It only contains balances for dates that a user has made a transaction. I need it to contain a row for each user with their balance on each date in a given date range. * If the user does not have a row for a given date in the range, I need to use their balance from the day before. * If the user created their account after a given date in the range, I need to avoid creating a row for that user/date combination. I can reference an accounts table to get users' create_date: ~~~pgsql CREATE TABLE accounts ( user_id INT , create_date DATE ); INSERT INTO accounts (user_id, create_date) VALUES (1, '2015-12-01') , (2, '2015-12-31') , (3, '2016-01-03') ; ~~~ My desired result looks like this: +---------+---------+--------------------------+ | user_id | balance | as_of_date | +---------+---------+--------------------------+ | 1 | 100 | 2016-01-03T00:00:00.000Z | | 1 | 50 | 2016-01-02T00:00:00.000Z | | 1 | 10 | 2016-01-01T00:00:00.000Z | | 2 | 200 | 2016-01-03T00:00:00.000Z | | 2 | 200 | 2016-01-02T00:00:00.000Z | | 2 | 200 | 2016-01-01T00:00:00.000Z | | 3 | 30 | 2016-01-03T00:00:00.000Z | +---------+---------+--------------------------+ Note that rows have been added for user 2 for 2016-01-02 and 2016-01-03, carrying over the previous balance from 2016-01-01; and that no rows have been added for user 3, who was created on 2016-01-03. To generate a series of dates in a date range, I know I can use: SELECT d.date FROM GENERATE_SERIES('2016-01-01', '2016-01-03', '1 day'::INTERVAL) d ...but I am struggling with LEFT JOINing that series with each set of rows grouped by user_id.
Asked by Shaun Scovil (341 rep)
Mar 25, 2016, 08:48 PM
Last activity: May 31, 2024, 03:29 AM