sql >> Base de Datos >  >> RDS >> Mysql

Agrupación de fecha y hora de MySQL en intervalos independientemente de la zona horaria

Puede usar TIMESTAMPDIFF para agrupar por intervalos de tiempo:

Para un intervalo específico de horas, puede usar:

SELECT   '2012-08-03 00:00:00' + 
         INTERVAL FLOOR(TIMESTAMPDIFF(HOUR, '2012-08-03 00:00:00', timestamp) / <n>) * <n> HOUR AS start_time,
         COUNT(*) AS total 
FROM     event 
WHERE    timestamp >= '2012-08-03 00:00:00'
GROUP BY start_time

Reemplace las ocurrencias de 2012-08-03 00:00:00 con su fecha mínima de entrada.

<n> es su intervalo especificado en horas (cada 2 horas, 3 horas, etc.), y puedes hacer lo mismo por minutos:

SELECT   '2012-08-03 00:00:00' + 
         INTERVAL FLOOR(TIMESTAMPDIFF(MINUTE, '2012-08-03 00:00:00', timestamp) / <n>) * <n> MINUTE AS start_time,
         COUNT(*) AS total 
FROM     event 
WHERE    timestamp >= '2012-08-03 00:00:00'
GROUP BY start_time

Donde <n> es su intervalo especificado en minutos (cada 45 minutos, 90 minutos, etc.).

Asegúrese de pasar la fecha de entrada mínima (en este ejemplo, 2012-08-03 00:00:00 ) como segundo parámetro para TIMESTAMPDIFF .

EDITAR: Si no quiere preocuparse por qué unidad de intervalo elegir en el TIMESTAMPDIFF luego, por supuesto, solo haga el intervalo por segundos (300 =5 minutos, 3600 =1 hora, 7200 =2 horas, etc.)

SELECT   '2012-08-03 00:00:00' + 
         INTERVAL FLOOR(TIMESTAMPDIFF(SECOND, '2012-08-03 00:00:00', timestamp) / <n>) * <n> SECOND AS start_time,
         COUNT(*) AS total 
FROM     event 
WHERE    timestamp >= '2012-08-03 00:00:00'
GROUP BY start_time

EDIT2: Para abordar su comentario relacionado con la reducción de la cantidad de áreas en la declaración en las que debe pasar la fecha mínima del parámetro, puede usar:

SELECT   b.mindate + 
         INTERVAL FLOOR(TIMESTAMPDIFF(SECOND, b.mindate, timestamp) / <n>) * <n> SECOND AS start_time,
         COUNT(*) AS total 
FROM     event 
JOIN     (SELECT '2012-08-03 00:00:00' AS mindate) b ON timestamp >= b.mindate
GROUP BY start_time

Y simplemente pase su parámetro mínimo de fecha y hora una vez en la subselección de unión.

Incluso puede hacer una segunda columna en la subselección de unión para su intervalo de segundos (por ejemplo, 3600 ) y nombre la columna algo así como secinterval ... luego cambie el <n> 's a b.secinterval , por lo que solo tiene que pasar su parámetro de fecha mínima Y el intervalo una vez cada uno.

Demostración de SQLFiddle