我想在时间轴上绘制my_values
的分辨率低于我在数据库中的分辨率。我使用类似下面的SQL来获取每个时间间隔的平均值(例如,一小时):
SELECT DATE_TRUNC('hour', my_timestamps) AS my_time_lowres
, AVG(my_values)
FROM my_table
GROUP BY my_time_lowres
使用date_trunc()
可以将时间戳的分辨率降低到一定程度(根据the docs):
select date_trunc('hour', timestamp '2001-02-16 20:38:40')
-- the output is: 2001-02-16 20:00:00
这样,我可以针对以下间隔大小(以及一些更大/更小的大小)执行此操作:
...
second
minute
hour
day
week
...
是否有办法在其他时间间隔内实现这一目标,例如3小时,6小时?
答案 0 :(得分:6)
考虑一下这个演示,可以将时间戳降低到15分钟的分辨率并汇总结果:
WITH tbl(id, ts) AS ( VALUES
(1::int, '2012-10-04 00:00:00'::timestamp)
,(2, '2012-10-04 18:23:01')
,(3, '2012-10-04 18:30:00')
,(4, '2012-10-04 18:52:33')
,(5, '2012-10-04 18:55:01')
,(6, '2012-10-04 18:59:59')
,(7, '2012-10-05 11:01:01')
)
SELECT to_timestamp((extract(epoch FROM ts)::bigint / 900)*900)::timestamp
AS lower_bound
, to_timestamp(avg(extract(epoch FROM ts)))::timestamp AS avg_ts
, count(*) AS ct
FROM tbl
GROUP BY 1
ORDER BY 1;
结果:
lower_bound | avg_ts | ct
---------------------+---------------------+----
2012-10-04 00:00:00 | 2012-10-04 00:00:00 | 1
2012-10-04 18:15:00 | 2012-10-04 18:23:01 | 1
2012-10-04 18:30:00 | 2012-10-04 18:30:00 | 1
2012-10-04 18:45:00 | 2012-10-04 18:55:51 | 3
2012-10-05 11:00:00 | 2012-10-05 11:01:01 | 1
诀窍是提取像@Michael已发布的unix时代。整数除法将它们整合在所选分辨率的桶中,因为小数位被截断。
我除以900,因为15分钟= 900秒。
乘以相同的数字得到结果lower_bound
。
将unix时期转换回to_timestamp()
的时间戳。
这对于可以在十进制系统中不使用小数位表示的区间非常有用。对于更多功能,请使用经常被忽略的函数width_bucket()
,就像我在此recent, closely related answer中演示的那样。更多解释,链接和那里的sqlfiddle演示。
答案 1 :(得分:0)
您可以转换为自纪元以来的秒数,并将整数除以3 * 3600,6 * 3600等。