Skip to content

Instantly share code, notes, and snippets.

@DanielJoyce
Last active April 17, 2020 22:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielJoyce/cc9f80d4326b7cb40d07af2ffb069b74 to your computer and use it in GitHub Desktop.
Save DanielJoyce/cc9f80d4326b7cb40d07af2ffb069b74 to your computer and use it in GitHub Desktop.
gap filling in off-the-shelf postgres

Schema (PostgreSQL v12)

CREATE TABLE test (ts timestamp, email varchar, title varchar);
insert into test values
('2017-01-01', 'me@me.com', 'Old title'),
('2017-01-02', 'me@me.com', null),
('2017-01-03', 'me@me.com', 'New Title'),
('2017-01-04', 'me@me.com', null),
('2017-01-05', 'me@me.com', null),
('2017-01-06', 'me@me.com', 'Newer Title'),
('2017-01-07', 'me@me.com', null),
('2017-01-08', 'me@me.com', null);

 -- The built in function coalesce is not a aggregate function, nor is variadic.
 -- It might just be a compiler construct.
 -- So we define our own version
 CREATE FUNCTION f_coalesce(a anyelement, b anyelement) RETURNS anyelement AS '
    SELECT COALESCE(a,b);
 ' LANGUAGE SQL PARALLEL SAFE;
 -- Aggregate colasce that keeps first non-null value it sees
CREATE AGGREGATE agg_coalesce (anyelement)
(
    sfunc = f_coalesce,
    stype = anyelement
);

Query #1

SELECT
    ts,
    email,
    
    array_agg(title) FILTER (WHERE title is not null ) OVER ( 
        order by ts desc ROWS BETWEEN current row and unbounded following 
    ) as title_array,
    (array_agg(title) FILTER (WHERE title is not null ) OVER ( 
        order by ts desc ROWS BETWEEN current row and unbounded following )
    )[1] as title,
    COALESCE(
        agg_coalesce(title) OVER ( 
            order by ts desc ROWS BETWEEN current row and unbounded following 
        ),
      	(select title from test 
         	where title is not null 
         	and ts < '2017-01-02'
         	order by ts desc limit 1 )
    )as title_locf 
from test
where ts >= '2017-01-02'
order by ts desc;
ts email title_array title title_locf
2017-01-08T00:00:00.000Z me@me.com Newer Title,New Title Newer Title Newer Title
2017-01-07T00:00:00.000Z me@me.com Newer Title,New Title Newer Title Newer Title
2017-01-06T00:00:00.000Z me@me.com Newer Title,New Title Newer Title Newer Title
2017-01-05T00:00:00.000Z me@me.com New Title New Title New Title
2017-01-04T00:00:00.000Z me@me.com New Title New Title New Title
2017-01-03T00:00:00.000Z me@me.com New Title New Title New Title
2017-01-02T00:00:00.000Z me@me.com Old title

View on DB Fiddle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment