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;
Le CTE t
fournit des données comme votre table pourrait contenir :un horodatage ts
par minute avec une bandwidth
Numéro. (Vous n'avez pas besoin de cette partie, vous travaillez avec votre table à la place.)
Voici une solution très similaire pour une question très similaire - avec une explication détaillée du fonctionnement de cette agrégation particulière :
- date_trunc intervalle de 5 minutes dans PostgreSQL
Voici une solution similaire pour une question similaire concernant la course sommes - avec des explications détaillées et des liens pour les différentes fonctions utilisées :
- PostgreSQL :nombre de lignes en cours pour une requête "par minute"
Question supplémentaire en commentaire
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;
Récupère un échantillon non agrégé par intervalle de 15 minutes - à partir de la dernière ligne disponible dans la fenêtre. Ce sera la 15e minute si la rangée ne manque pas. Les parties cruciales sont DISTINCT ON
et ORDER BY
.
Plus d'informations sur la technique utilisée ici :
- Sélectionner la première ligne de chaque groupe GROUP BY ?