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
poskytuje data, jako by mohla obsahovat vaše tabulka:jedno časové razítko ts
za minutu s bandwidth
číslo. (Tu část nepotřebujete, místo toho pracujete se svým stolem.)
Zde je velmi podobné řešení pro velmi podobnou otázku - s podrobným vysvětlením, jak tato konkrétní agregace funguje:
- date_trunc 5minutový interval v PostgreSQL
Zde je podobné řešení pro podobnou otázku týkající se běhu součty – s podrobným vysvětlením a odkazy na různé použité funkce:
- PostgreSQL:průběžný počet řádků pro dotaz „po minutách“
Dodatečná otázka v komentáři
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;
Načte jeden neagregovaný vzorek za 15minutový interval – z posledního dostupného řádku v okně. Pokud řada nebude chybět, bude to 15. minuta. Rozhodující části jsou DISTINCT ON
a ORDER BY
.
Více informací o použité technice zde:
- Vybrat první řádek v každé skupině GROUP BY?