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
tillhandahåller data som din tabell kan innehålla:en tidsstämpel ts
per minut med en bandwidth
siffra. (Du behöver inte den delen, du arbetar med ditt bord istället.)
Här är en mycket liknande lösning för en mycket liknande fråga - med detaljerad förklaring hur just denna aggregering fungerar:
- date_trunc 5 minuters intervall i PostgreSQL
Här är en liknande lösning för en liknande fråga angående löpning summor - med detaljerad förklaring och länkar för de olika funktionerna som används:
- PostgreSQL:löpande antal rader för en fråga "per minut"
Ytterligare fråga 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;
Hämtar en oaggregerat prov per 15 minuters intervall - från den sista tillgängliga raden i fönstret. Detta blir den 15:e minuten om raden inte saknas. Avgörande delar är DISTINCT ON
och ORDER BY
.
Mer information om den använda tekniken här:
- Välj första raden i varje GROUP BY-grupp?