SELECT grid.t5
,min(t."time") AS min_time
-- ,array_agg(extract(min FROM t."time")) AS 'players_on' -- optional
,avg(t.players) AS avg_players
,avg(t.servers) AS avg_servers
FROM (
SELECT generate_series(min("time")
,max("time"), interval '5 min') AS t5
FROM tbl
) grid
LEFT JOIN tbl t ON t."time" >= grid.t5
AND t."time" < grid.t5 + interval '5 min'
GROUP BY grid.t5
ORDER BY grid.t5;
Expliquez
-
La sous-requête
grid
produit une ligne toutes les 5 minutes du minimum au maximum de "time"
dans votre tableau. -
LEFT JOIN revient à la table en découpant les données en intervalles de 5 minutes. Inclure soigneusement bordure inférieure et exclure bordure supérieure.
-
Pour supprimer des créneaux de 5 minutes où rien ne s'est passé, utilisez
JOIN
à la place deLEFT JOIN
. -
Pour que vos temps de grille commencent à 0:00, 5:00 etc, arrondissez le
min("time")
dansgenerate_series()
.
Plus d'explications dans ces réponses associées :
Regrouper par intervalles de données
PostgreSQL :nombre de lignes en cours pour une requête "par minute"
A part :je n'utiliserais pas time
comme identifiant. C'est un mot réservé en SQL standard
et un nom de fonction/type dans Postgres.