Du kan generere en tabel med "buckets" ved at tilføje intervaller oprettet af gener_series(). Denne SQL-sætning genererer en tabel med fem-minutters buckets for den første dag (værdien af min(measured_at)
) i dine data.
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
Indpak det sætning i et almindeligt tabeludtryk, og du kan tilslutte og gruppere på det, som om det var en basistabel.
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
Gruppering efter et vilkårligt antal sekunder er ens - brug date_trunc()
.
En mere generel brug af gener_series() lader dig undgå at gætte den øvre grænse for fem-minutters buckets. I praksis ville du sandsynligvis bygge dette som en visning eller en funktion. Du får muligvis bedre ydeevne fra en basistabel.
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;