PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Nombre glissant de lignes dans un intervalle de temps

Sons comme une application pour les fonctions de fenêtre . Mais, malheureusement, ce n'est pas le cas. Les cadres de fenêtre ne peuvent être basés que sur le nombre de lignes, pas sur les valeurs réelles des colonnes.

Une requête simple avec LEFT JOIN peut faire le travail :

SELECT t0.order_id
     , count(t1.time_created) AS count_within_3_sec
FROM   tbl      t0
LEFT   JOIN tbl t1 ON t1.time_created BETWEEN t0.time_created - interval '3 sec'
                                          AND t0.time_created
GROUP  BY 1
ORDER  BY 1;

db<>violon ici

Ne fonctionne pas avec time comme dans votre démo minimale, car cela ne tourne pas rond. Je suppose qu'il est raisonnable de supposer timestamp ou timestamptz .

Puisque vous incluez chaque ligne elle-même dans le décompte, un INNER JOIN fonctionnerait aussi. (LEFT JOIN est encore plus fiable face à d'éventuelles valeurs NULL.)

Ou utilisez un LATERAL sous-requête et vous n'avez pas besoin d'agréger au niveau de la requête externe :

SELECT t0.order_id
     , t1.count_within_3_sec
FROM   tbl t0
LEFT   JOIN LATERAL (
   SELECT count(*) AS count_within_3_sec
   FROM   tbl t1
   WHERE  t1.time_created BETWEEN t0.time_created - interval '3 sec'
                              AND t0.time_created
   ) t1 ON true
ORDER  BY 1;

Connexe :

Pour les grandes tables et de nombreuses lignes dans le laps de temps, une solution procédurale qui parcourt la table une fois sera plus performant. Comme :