By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
CREATE TABLE tbl (date date, email text);
INSERT INTO tbl VALUES
('2012-01-01', 'test@test.com')
, ('2012-01-01', 'test1@test.com')
, ('2012-01-01', 'test2@test.com')
, ('2012-01-02', 'test1@test.com')
, ('2012-01-02', 'test2@test.com')
-- , ('2012-01-03', 'test@test.com') -- no entry for this day
, ('2012-01-04', 'test@test.com')
, ('2012-01-05', 'test@test.com')
, ('2012-01-05', 'test@test.com')
, ('2012-01-06', 'test@test.com')
, ('2012-01-06', 'test@test.com')
, ('2012-01-06', 'test1@test.com`')
;
CREATE TABLE
INSERT 0 11
-- only days with entry
SELECT date
,(SELECT count(DISTINCT email)
FROM tbl
WHERE date BETWEEN t.date - 2 AND t.date -- period of 3 days
) AS dist_emails
FROM tbl t
WHERE date BETWEEN '2012-01-01' AND '2012-01-06'
GROUP BY 1
ORDER BY 1;
date | dist_emails |
---|---|
2012-01-01 | 3 |
2012-01-02 | 3 |
2012-01-04 | 3 |
2012-01-05 | 1 |
2012-01-06 | 2 |
SELECT 5
-- all days
SELECT date
,(SELECT count(DISTINCT email)
FROM tbl
WHERE date BETWEEN g.date - 2 AND g.date
) AS dist_emails
FROM (SELECT generate_series(timestamp '2012-01-01'
, timestamp '2012-01-06'
, interval '1 day')::date) AS g(date);
date | dist_emails |
---|---|
2012-01-01 | 3 |
2012-01-02 | 3 |
2012-01-03 | 3 |
2012-01-04 | 3 |
2012-01-05 | 1 |
2012-01-06 | 2 |
SELECT 6
SELECT g.date, count(DISTINCT email) AS dist_emails
FROM (SELECT generate_series(timestamp '2012-01-01'
, timestamp '2012-01-06'
, interval '1 day')::date) AS g(date)
LEFT JOIN tbl t ON t.date BETWEEN g.date - 2 AND g.date
GROUP BY 1
ORDER BY 1;
date | dist_emails |
---|---|
2012-01-01 | 3 |
2012-01-02 | 3 |
2012-01-03 | 3 |
2012-01-04 | 3 |
2012-01-05 | 1 |
2012-01-06 | 2 |
SELECT 6