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
dostarcza dane, które może przechowywać Twoja tabela:jeden znacznik czasu ts
na minutę z bandwidth
numer. (Nie potrzebujesz tej części, zamiast tego pracujesz ze swoim stołem.)
Oto bardzo podobne rozwiązanie dla bardzo podobnego pytania - ze szczegółowym wyjaśnieniem, jak działa ta konkretna agregacja:
- date_trunc 5-minutowy interwał w PostgreSQL
Oto podobne rozwiązanie dla podobnego pytania dotyczącego biegania sumy - ze szczegółowym wyjaśnieniem i linkami do różnych używanych funkcji:
- PostgreSQL:liczenie wierszy dla zapytania „po minucie”
Dodatkowe pytanie w komentarzu
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;
Pobiera jeden próbka niezagregowana na 15-minutowy interwał — z ostatniego dostępnego wiersza w oknie. Będzie to 15 minuta, jeśli nie brakuje rzędu. Kluczowe części to DISTINCT ON
i ORDER BY
.
Więcej informacji o zastosowanej technice tutaj:
- Wybrać pierwszy wiersz w każdej grupie GROUP BY?