string_agg sort postgres json_object_agg functions ejemplos array_to_string array_agg array agg sql postgresql nosql aggregate-functions generate-series

sort - select array_agg postgresql



Agrupar por intervalos de datos (2)

Tengo una sola tabla que almacena el uso del ancho de banda en la red durante un período de tiempo. Una columna contendrá la fecha y hora (clave principal) y otra columna registrará el ancho de banda. Los datos se graban cada minuto. Tendremos otras columnas registrando otros datos en ese momento.

Si el usuario solicita los datos en intervalos de 15 minutos (dentro de un período de 24 horas con fecha de inicio y finalización), ¿es posible con una única consulta obtener los datos que necesito o tendré que escribir un procedimiento / cursor almacenado para hacer esto? ? Los usuarios pueden luego solicitar datos de intervalos de 5 minutos, etc.

Lo más probable es que esté usando Postgres, pero ¿hay otras opciones de NOSQL que serían mejores?

¿Algunas ideas?


select date_trunc(''hour'', d) + (((extract(minute from d)::integer / 5 * 5)::text) || '' minute'')::interval as "from", date_trunc(''hour'', d) + ((((extract(minute from d)::integer / 5 + 1) * 5)::text) || '' minute'')::interval - ''1 second''::interval as "to", sum(random() * 1000) as bandwidth from generate_series(''2012-01-01'', ''2012-01-31'', ''1 minute''::interval) s(d) group by 1, 2 order by 1, 2 ;

Eso durante 5 minutos varía. Por 15 minutos divide por 15.


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;

El CTE t proporciona datos como su tabla podría contener: una marca de tiempo ts por minuto con un número de bandwidth . (No necesita esa parte, en su lugar trabaja con su mesa).

Aquí hay una solución muy similar para una pregunta muy similar, con una explicación detallada de cómo funciona esta agregación en particular:

Aquí hay una solución similar para una pregunta similar sobre sumas en ejecución , con explicación detallada y enlaces para las diversas funciones utilizadas:

Pregunta adicional en comentario

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 una muestra no agregada por intervalo de 15 minutos, desde la última fila disponible en la ventana. Este será el minuto 15 si la fila no falta. Las partes cruciales son DISTINCT ON y ORDER BY .
Más información sobre la técnica utilizada aquí: