Reputation: 1208
I’m using PostgreSQL and I try to realize how to build the query for calculating the count of each status of event per date in the range
| dateStart | dateEnd | status |
|----------------------------------|
| 2019-02-10 | 2019-02-11 | Type1 |
| 2019-02-10 | 2019-02-16 | Type1 |
| 2019-02-10 | 2019-02-12 | Type2 |
| 2019-02-11 | 2019-02-16 | Type1 |
| 2019-02-12 | 2019-02-14 | Type2 |
| 2019-02-13 | null | Type2 |
| 2019-02-12 | 2019-02-13 | Type2 |
| 2019-02-15 | 2019-02-16 | Type3 |
| 2019-02-14 | 2019-02-14 | Type1 |
Event starts from dateStart and ends by dateEnd (or null if it is still in progress) and have to be counted in every date in range if dateStart-dateEnd somehow cross query date range.
I have a date range, for example:
from: 2019-02-12
to: 2019-02-15
| date | type1Count | type2Count | type3Count |
|---------------------------------------------------|
| 2019-02-12 | 2 | 3 | 0 |
| 2019-02-13 | 2 | 3 | 0 |
| 2019-02-14 | 3 | 2 | 0 |
| 2019-02-15 | 2 | 1 | 1 |
SELECT DATE_TRUNC('day', "events"."dateStart") AS dateStart,
COUNT(CASE WHEN "events"."status" = 'Type1' THEN 1 END) AS "Type1",
COUNT(CASE WHEN "events"."status" = 'Type2' THEN 1 END) AS "Type2",
COUNT(CASE WHEN "events"."status" = 'Type3' THEN 1 END) AS "Type3",
FROM "events"
GROUP BY 1
ORDER BY 1;
Upvotes: 0
Views: 51
Reputation: 1269873
The simplest method is Postgres is use to generate_series()
:
select d.dte, count(e.type) as total,
count(*) filter (where e.type = 'Type1') as type1_cnt,
count(*) filter (where e.type = 'Type2') as type2_cnt,
count(*) filter (where e.type = 'Type3') as type3_cnt
from (select generate_series(min(datestart), max(datestart), interval '1 day') as dte
from events
) d left join
events e
on d.dte >= e.datestart and d.dte <= e.dateend
group by d.dte
order by d.dte;
Upvotes: 1