Mysql
 sql >> Database >  >> RDS >> Mysql

Raggruppare MySQL datetime in intervalli indipendentemente dal fuso orario

Puoi utilizzare TIMESTAMPDIFF per raggruppare per intervalli di tempo:

Per un intervallo di ore specificato, puoi utilizzare:

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

Sostituisci le occorrenze di 2012-08-03 00:00:00 con la tua data di input minima.

<n> è l'intervallo specificato in ore (ogni 2 ore, 3 ore, ecc.), e puoi fare lo stesso per minuti:

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

Dove <n> è l'intervallo specificato in minuti (ogni 45 minuti, 90 minuti, ecc.).

Assicurati di aver inserito la data di input minima (in questo esempio 2012-08-03 00:00:00 ) come secondo parametro per TIMESTAMPDIFF .

MODIFICA: Se non vuoi preoccuparti di quale unità di intervallo scegliere nel TIMESTAMPDIFF funzione, quindi ovviamente fai l'intervallo per secondi (300 =5 minuti, 3600 =1 ora, 7200 =2 ore, ecc.)

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: Per indirizzare il tuo commento relativo alla riduzione del numero di aree nella dichiarazione in cui devi passare la data del parametro minimo, puoi utilizzare:

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 passa semplicemente il tuo parametro datetime minimo una volta nella sottoselezione di join.

Puoi anche creare una seconda colonna nella sottoselezione di join per il tuo intervallo di secondi (ad es. 3600 ) e nominare la colonna in modo simile a secinterval ... quindi cambia il <n> 's a b.secinterval , quindi devi solo passare il parametro della data minima E l'intervallo una volta ciascuno.

Demo SQLFiddle