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;
De CTE t
biedt gegevens zoals uw tabel zou kunnen bevatten:één tijdstempel ts
per minuut met een bandwidth
nummer. (Je hebt dat deel niet nodig, je werkt in plaats daarvan met je tabel.)
Hier is een zeer vergelijkbare oplossing voor een zeer vergelijkbare vraag - met gedetailleerde uitleg hoe deze specifieke aggregatie werkt:
- date_trunc interval van 5 minuten in PostgreSQL
Hier is een vergelijkbare oplossing voor een vergelijkbare vraag over hardlopen sommen - met gedetailleerde uitleg en links voor de verschillende gebruikte functies:
- PostgreSQL:lopende telling van rijen voor een zoekopdracht 'per minuut'
Aanvullende vraag in opmerking
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;
Haalt één op niet-geaggregeerde steekproef per interval van 15 minuten - van de laatst beschikbare rij in het raam. Dit is de 15e minuut als de rij niet ontbreekt. Cruciale onderdelen zijn DISTINCT ON
en ORDER BY
.
Meer informatie over de gebruikte techniek hier:
- Selecteer de eerste rij in elke GROUP BY-groep?