PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Raggruppa per intervalli di dati

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;

Il CTE t fornisce dati come potrebbe contenere la tua tabella:un timestamp ts al minuto con una bandwidth numero. (Non hai bisogno di quella parte, lavori invece con il tuo tavolo.)

Ecco una soluzione molto simile per una domanda molto simile, con una spiegazione dettagliata di come funziona questa particolare aggregazione:

  • date_trunc intervallo di 5 minuti in PostgreSQL

Ecco una soluzione simile per una domanda simile relativa alla corsa somme - con spiegazione dettagliata e link per le varie funzioni utilizzate:

  • PostgreSQL:conteggio in esecuzione delle righe per una query 'per minuto'

Domanda aggiuntiva nel commento

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;

Recupera uno campione non aggregato per intervallo di 15 minuti - dall'ultima riga disponibile nella finestra. Questo sarà il 15° minuto se la riga non manca. Le parti cruciali sono DISTINCT ON e ORDER BY .
Ulteriori informazioni sulla tecnica utilizzata qui:

  • Seleziona la prima riga in ogni gruppo GROUP BY?