PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Agrupar por intervalos de dados

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;

O CTE t fornece dados como sua tabela pode conter:um timestamp ts por minuto com uma bandwidth número. (Você não precisa dessa parte, você trabalha com sua mesa.)

Aqui está uma solução muito semelhante para uma pergunta muito semelhante - com uma explicação detalhada de como essa agregação específica funciona:
  • date_trunc intervalo de 5 minutos no PostgreSQL

Aqui está uma solução semelhante para uma pergunta semelhante sobre execução somas - com explicação detalhada e links para as várias funções utilizadas:
  • PostgreSQL:contagem de linhas em execução para uma consulta 'por minuto'

Pergunta adicional no comentário

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 um amostra não agregada por intervalo de 15 minutos - da última linha disponível na janela. Este será o 15º minuto se a linha não estiver faltando. As peças cruciais são DISTINCT ON e ORDER BY .
Mais informações sobre a técnica utilizada aqui:
  • Selecionar a primeira linha em cada grupo GROUP BY?