Reputation: 16836
I have a table with a few fields, but I just want to count the entries per day where the state
field is e.g. 'rejected'. The field createdAt
is a timestamp with timezone.
id | createdAt | state
------------------------------------------
1 | 2018-01-17 13:53:17.303+00 | rejected
2 | 2017-10-19 20:39:18.232+00 | approved
So I want to count the rows for each day between two timestamps. Days without any entry should return 0 or NULL. The query I created returns the correct time series, but somehow my join or count seems to be odd. It returns me thousands of entries, but there are usually just between 0 and 20. (Whole table is less than 3800 entries)
SELECT serie.day AS time, count(t."createdAt") AS created
FROM (
SELECT generate_series(
to_timestamp(1518248353)::date,
to_timestamp(1521469246)::date,
interval '1 day'
) AS day
FROM users t
) serie
LEFT JOIN users t ON t."createdAt"::date = serie.day::date
WHERE state ILIKE 'rejected'
GROUP BY serie.day
ORDER BY time;
Wrong result:
2018-02-10 00:00:00+00 11619
2018-02-11 00:00:00+00 23238
2018-02-12 00:00:00+00 27111
2018-02-13 00:00:00+00 19365
2018-02-14 00:00:00+00 15492
2018-02-15 00:00:00+00 34857
2018-02-16 00:00:00+00 34857
2018-02-17 00:00:00+00 15492
2018-02-18 00:00:00+00 46476
2018-02-19 00:00:00+00 15492
2018-02-21 00:00:00+00 27111
2018-02-22 00:00:00+00 19365
2018-02-23 00:00:00+00 11619
2018-02-24 00:00:00+00 3873
2018-02-25 00:00:00+00 3873
...
Expected result something like this:
2018-02-10 00:00:00+00 3
2018-02-11 00:00:00+00 9
2018-02-12 00:00:00+00 0
2018-02-13 00:00:00+00 19
2018-02-14 00:00:00+00 15
2018-02-15 00:00:00+00 3
2018-02-16 00:00:00+00 7
...
Upvotes: 2
Views: 3022
Reputation: 4820
Why are you joining your generated series to the user table in the subquery? I think that's your problem. Normally, when you use generate_series()
you just provide start datetime, end datetime, and interval, and it generates that series as a table.
Try this instead:
SELECT
serie.day AS time,
COUNT(t."createdAt") AS created
FROM (
SELECT date_series::date AS day
FROM generate_series(
to_timestamp(1518248353)::date,
to_timestamp(1521469246)::date,
'1 day'
) AS date_series
) AS serie
LEFT JOIN users t ON t."createdAt"::date = serie.day::date
AND state ILIKE 'rejected'
GROUP BY serie.day
ORDER BY time;
Upvotes: 5