Reputation: 243
I have table, like this:
| id | datetime | resource |
|:---|---------:|:--------:|
| 1 |2019-12-18| /v1 |
| 2 |2019-12-18| /v1 |
| 3 |2019-12-18| /v2 |
| 4 |2019-12-27| /v3 |
I need count resource per day. And I can't understand how to build query for getting like this:
| id | datetime | resource | count |
|:---|---------:|:--------:|:-----:|
| 1 |2019-12-18| /v1 | 2 |
| 2 |2019-12-18| /v2 | 1 |
| 3 |2019-12-18| /v3 | 0 |
| 4 |2019-12-27| /v3 | 1 |
| 5 |2019-12-27| /v1 | 0 |
| 6 |2019-12-27| /v2 | 0 |
Upvotes: 1
Views: 92
Reputation: 1270623
Use a cross join
to generate the rows. Then use a left join
to bring in the original values and aggregation:
select row_number() over (order by r.resource, d.datetime) as seqnum,
d.datetime, r.resource,
count(t.id) as cnt
from (select distinct datetime from t) d cross join
(select distinct resource from t) r left join
t
on d.datetime = t.datetime and
r.resource = t.resource
group by d.datetime, r.resource
order by seqnum;
Here is a db<>fiddle.
Upvotes: 0
Reputation: 65363
One option would be using CROSS JOIN
to determine cross product relation among resource
and datetime
columns and then LEFT JOIN
to combine with subquery in which there are grouped resource
and datetime
columns containing aggregation :
SELECT row_number() over (ORDER BY datetime, count DESC, resource) AS ID,
q.*
FROM
( SELECT t3.datetime, t3.resource, COALESCE(t4.count,0) AS count
FROM
(
(SELECT distinct resource FROM tab) t1
CROSS JOIN (SELECT distinct datetime FROM tab) t2 ) t3
LEFT JOIN
(
SELECT datetime, resource,count(datetime) as count
FROM tab
GROUP BY datetime, resource
) t4
ON t4.datetime = t3.datetime
AND t4.resource = t3.resource
) q;
Upvotes: 2
Reputation: 2296
Please try like below. IE. Group by
with datetime and resource then take the count
for the same you will get the Output . Please try this.
SELECT datetime, resource,count(id) AS count
FROM public.test GROUP BY datetime,resource;
Output
datetime resource count
18-12-2019 /v2 1
18-12-2019 /v1 2
27-12-2019 /v3 1
Upvotes: 0