2009-12-10 9 views
7

Básicamente, quiero agregar algunos valores en una tabla de acuerdo con un intervalo de tiempo.Agregando datos por intervalo de tiempo en MySQL

Lo que hago es tomar instantáneas de un sistema cada 15 minutos y quiero dibujar un gráfico durante un período prolongado. Dado que los gráficos son realmente confusos si se muestran demasiados puntos (además de ser muy lento de renderizar), quiero reducir el número de puntos al agregar varios puntos en un solo punto promediando sobre ellos.

Para esto tendría que ser capaz de agrupar por cubos que puedo definir por mí (diariamente, semanalmente, mensualmente, anualmente, ...) pero hasta ahora todos mis experimentos no han tenido suerte.

¿Hay algún truco que pueda solicitar para hacerlo?

Respuesta

10

Tuve una pregunta similar: collating-stats-into-time-chunks y me respondieron muy bien. En esencia, la respuesta fue:

Quizás pueda usar la función DATE_FORMAT() y la agrupación. Aquí hay un ejemplo, espero que pueda adaptarse a sus necesidades precisas.

SELECT 
    DATE_FORMAT(time, "%H:%i"), 
    SUM(bytesIn), 
    SUM(bytesOut) 
FROM 
    stats 
WHERE 
    time BETWEEN <start> AND <end> 
GROUP BY 
    DATE_FORMAT(time, "%H:%i") 

Si su ventana de tiempo abarca más de un día y se utiliza el formato de ejemplo, los datos de diferentes días se agregarán en los cubos 'hora-de-día. Si los datos brutos no caen exactamente en la hora, puede suavizarlos usando "% H: 00".

Gracias a Martin Clayton por la respuesta que me dio.

+0

hace esto escala? Mi problema es que esto producirá varios millones de entradas después de un año. – cdecker

+1

No puedo ver por qué no lo haría. Obviamente, hacer cualquier tipo de conversión de tiempo es lento, pero la mayor parte del tiempo se invertirá en la agregación de datos, lo cual es inevitable en su caso. – cmroanirgo

2

Es fácil para truncar veces para los últimos 15 minutos (por ejemplo), haciendo algo como:

SELECT dateadd(minute, datediff(minute, '20000101', yourDateTimeField)/15 * 15, '20000101') AS the15minuteBlock, COUNT(*) as Cnt 
FROM yourTable 
GROUP BY dateadd(minute, datediff(minute, '20000101', yourDateTimeField)/15 * 15, '20000101'); 

utilizar los mismos métodos de truncamiento para agrupar por hora, semana, lo que sea.

Siempre se puede envolverlo en una sentencia CASE para manejar múltiples métodos, usando:

GROUP BY CASE @option WHEN 'week' THEN dateadd(week, ..... 
Cuestiones relacionadas