[英]sql script to group hourly using datepart and fill the empty with 0
This script gives the hourly count of the timestamps in the table.此脚本提供表中时间戳的每小时计数。
SELECT date_trunc('hour', s.fill_instant) h , count(date_trunc('hour', s.fill_instant)) c FROM sms s
left join station s2 on
s.station_id = s2.station_id
where
s2.address like '%arizona%' and s.fill_date between '2021-09-19' and '2021-09-19'
GROUP BY date_trunc('hour', s.fill_instant)
order by date_trunc('hour', s.fill_instant) asc;
in the table like the following在如下表中
2021-09-19 00:00:00 3
2021-09-19 02:00:00 20
2021-09-19 03:00:00 6
2021-09-19 13:00:00 7
2021-09-19 14:00:00 11
2021-09-19 15:00:00 6
How can I insert the Zeros in the non present hours.如何在非当前时间插入零。 so it shows the map of complete 24 hours.所以它显示了完整的24小时地图。 much like this很像这样
2021-09-19 00:00:00 3
2021-09-19 01:00:00 0
2021-09-19 02:00:00 20
2021-09-19 03:00:00 6
2021-09-19 04:00:00 0
2021-09-19 05:00:00 0
2021-09-19 06:00:00 0
2021-09-19 07:00:00 0
2021-09-19 08:00:00 0
2021-09-19 09:00:00 0
2021-09-19 10:00:00 0
2021-09-19 11:00:00 0
2021-09-19 12:00:00 0
2021-09-19 13:00:00 7
2021-09-19 14:00:00 11
2021-09-19 15:00:00 6
2021-09-19 16:00:00 0
2021-09-19 17:00:00 0
2021-09-19 18:00:00 0
2021-09-19 19:00:00 0
2021-09-19 20:00:00 0
2021-09-19 21:00:00 0
2021-09-19 22:00:00 0
2021-09-19 23:00:00 0
2021-09-19 24:00:00 0
Use generate_series
to get all hours for the given day as a CTE then left join
it with your query:使用generate_series
获取给定日期的所有小时数作为 CTE,然后left join
其与您的查询结合起来:
WITH hours as (Select * from generate_series('2021-09-19 00:00:00'::timestamp, '2021-09-19 23:59:59'::timestamp, INTERVAL '1 hour') as hr)
SELECT hours.hr, coalesce(qry.c, 0) as c
FROM hours
LEFT JOIN(SELECT date_trunc('hour', s.fill_instant) h , count(date_trunc('hour', s.fill_instant)) c FROM sms s
left join station s2 on s.station_id = s2.station_id
where
s2.address like '%arizona%' and s.fill_date between '2021-09-19' and '2021-09-19'
GROUP BY date_trunc('hour', s.fill_instant)
order by date_trunc('hour', s.fill_instant) asc) qry on qry.h = hours.hr
A more or less generic pattern for filling gaps in a sequence would be this:填充序列中的空白或多或少的通用模式是这样的:
Use your existing query ( t
) and outer join it with the dense sequence of hours ( ds
).使用您现有的查询 ( t
) 并将其与密集的小时序列 ( ds
) 进行外部连接。 Use coalesce
to set null
values of tc
as 0.使用coalesce
将tc
null
值设置为0。
with t as
(
.. your query here ..
)
select ds.h, coalesce(t.c, 0) c
from generate_series
(
timestamp '2021-09-19T00:00:00',
timestamp '2021-09-19T24:00:00',
interval '1 hour'
) as ds(h)
left outer join t on t.h = ds.h;
Another way to generate all hours of a day is use a recursive query.另一种生成一天中所有小时的方法是使用递归查询。
Then you have to make a LEFT JOIN
between hours
subquery and your query, and in those rows that do not match your query ( c
column is null), you have to put a zero (I used a CASE
statement).然后您必须在hours
子查询和您的查询之间进行LEFT JOIN
,并且在那些与您的查询不匹配的行中( c
列为空),您必须放置一个零(我使用了CASE
语句)。
WITH RECURSIVE hours AS (SELECT '2021-09-19 00:00:00'::timestamp AS hour
UNION ALL
SELECT hour + interval '1 hour'
FROM hours
WHERE hour < '2021-09-19 23:00:00')
SELECT hours.hour, CASE WHEN sq.c IS NULL THEN 0 ELSE sq.c END AS c
FROM hours
LEFT JOIN (SELECT date_trunc('hour', s.fill_instant) h, count(date_trunc('hour', s.fill_instant)) c
FROM sms s
LEFT JOIN station s2 ON s.station_id = s2.station_id
WHERE s2.address like '%arizona%' AND s.fill_date = '2021-09-19'
GROUP BY date_trunc('hour', s.fill_instant)) AS sq ON hours.hour = sq.h
ORDER BY hours.hour;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.