WITH t AS (
SELECT ts, (random()*100)::int AS bandwidth
FROM generate_series('2012-09-01', '2012-09-04', '1 minute'::interval) ts
)
SELECT date_trunc('hour', ts) AS hour_stump
,(extract(minute FROM ts)::int / 15) AS min15_slot
,count(*) AS rows_in_timeslice -- optional
,sum(bandwidth) AS sum_bandwidth
FROM t
WHERE ts >= '2012-09-02 00:00:00+02'::timestamptz -- user's time range
AND ts < '2012-09-03 00:00:00+02'::timestamptz -- careful with borders
GROUP BY 1, 2
ORDER BY 1, 2;
CTE t
giver data som din tabel kan indeholde:et tidsstempel ts
minut med en bandwidth
nummer. (Du behøver ikke den del, du arbejder med dit bord i stedet.)
Her er en meget lignende løsning til et meget lignende spørgsmål - med detaljeret forklaring på, hvordan denne særlige aggregering fungerer:
- date_trunc 5 minutters interval i PostgreSQL
Her er en lignende løsning på et lignende spørgsmål vedrørende løb summer - med detaljeret forklaring og links til de forskellige anvendte funktioner:
- PostgreSQL:kørende antal rækker for en forespørgsel 'efter minut'
Yderligere spørgsmål i kommentaren
WITH -- same as above ...
SELECT DISTINCT ON (1,2)
date_trunc('hour', ts) AS hour_stump
,(extract(minute FROM ts)::int / 15) AS min15_slot
,bandwidth AS bandwith_sample_at_min15
FROM t
WHERE ts >= '2012-09-02 00:00:00+02'::timestamptz
AND ts < '2012-09-03 00:00:00+02'::timestamptz
ORDER BY 1, 2, ts DESC;
Henter én ikke-aggregeret prøve pr. 15 minutters interval - fra den sidste tilgængelige række i vinduet. Dette vil være det 15. minut, hvis rækken ikke mangler. Afgørende dele er DISTINCT ON
og ORDER BY
.
Mere information om den anvendte teknik her:
- Vælg første række i hver GROUP BY-gruppe?