您可以通过添加由 generate_series() 创建的间隔来生成“桶”表。min(measured_at)
此 SQL 语句将为您的数据中的第一天(的值)生成一个五分钟存储桶表。
select
(select min(measured_at)::date from measurements) + ( n || ' minutes')::interval start_time,
(select min(measured_at)::date from measurements) + ((n+5) || ' minutes')::interval end_time
from generate_series(0, (24*60), 5) n
将该语句包装在一个公用表表达式中,您可以在其上加入和分组,就好像它是一个基表一样。
with five_min_intervals as (
select
(select min(measured_at)::date from measurements) + ( n || ' minutes')::interval start_time,
(select min(measured_at)::date from measurements) + ((n+5) || ' minutes')::interval end_time
from generate_series(0, (24*60), 5) n
)
select f.start_time, f.end_time, avg(m.val) avg_val
from measurements m
right join five_min_intervals f
on m.measured_at >= f.start_time and m.measured_at < f.end_time
group by f.start_time, f.end_time
order by f.start_time
按任意秒数分组是类似的——使用date_trunc()
.
更一般地使用 generate_series() 可以让您避免猜测五分钟存储桶的上限。在实践中,您可能会将其构建为视图或函数。您可能会从基表中获得更好的性能。
select
(select min(measured_at)::date from measurements) + ( n || ' minutes')::interval start_time,
(select min(measured_at)::date from measurements) + ((n+5) || ' minutes')::interval end_time
from generate_series(0, ((select max(measured_at)::date - min(measured_at)::date from measurements) + 1)*24*60, 5) n;