Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Agrupando a data e hora do MySQL em intervalos, independentemente do fuso horário


Você pode usar TIMESTAMPDIFF para agrupar por intervalos de tempo:

Para um intervalo de horas especificado, você pode 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

Substitua as ocorrências de 2012-08-03 00:00:00 com sua data mínima de entrada.

<n> é o intervalo especificado em horas (cada 2 horas, 3 horas, etc.), e você pode fazer o mesmo 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

Onde <n> é o intervalo especificado em minutos (a cada 45 minutos, 90 minutos, etc).

Certifique-se de passar a data mínima de entrada (neste exemplo 2012-08-03 00:00:00 ) como o segundo parâmetro para TIMESTAMPDIFF .

EDITAR: Se você não quiser se preocupar com qual unidade de intervalo escolher no TIMESTAMPDIFF função, então, é claro, basta fazer o 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 seu comentário referente à redução do número de áreas na declaração em que você deve passar sua data mínima de parâmetro, você pode 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

E simplesmente passe seu parâmetro datetime mínimo uma vez na subseleção de junção.

Você pode até criar uma segunda coluna na subseleção de junção para seu intervalo de segundos (por exemplo, 3600 ) e nomeie a coluna como secinterval ... e altere o <n> 's para b.secinterval , então você só precisa passar seu parâmetro de data mínimo E intervalo uma vez cada.

Demonstração do SQLFiddle