Para empezar, resumamos el número de entradas por hora en su tabla.
SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
COUNT(*) samplecount
FROM table
GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)
Ahora, si registra algo cada seis minutos (diez veces por hora), todos sus valores de muestra deberían ser diez. Esta expresión: CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)
se ve peluda pero simplemente trunca tus marcas de tiempo a la hora en que ocurren poniendo a cero el minuto y el segundo.
Esto es razonablemente eficiente y lo ayudará a comenzar. Es muy eficiente si puede poner un índice en su columna entry_time y restringir su consulta a, digamos, muestras de ayer como se muestra aquí.
SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
COUNT(*) samplecount
FROM table
WHERE entry_time >= CURRENT_DATE - INTERVAL 1 DAY
AND entry_time < CURRENT_DATE
GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)
Pero no es muy bueno para detectar horas completas que pasan sin muestras faltantes. También es un poco sensible a la inestabilidad en su muestreo. Es decir, si su muestra del mejor horario es, a veces, medio segundo antes (10:59:30) y, a veces, medio segundo tarde (11:00:30), sus recuentos de resumen por hora estarán desactivados. Por lo tanto, este resumen de horas (o resumen de días, o resumen de minutos, etc.) no es a prueba de balas.
Necesita una consulta de auto combinación para hacer las cosas perfectamente bien; es un poco más una bola de pelo y no es tan eficiente.
Comencemos creando una tabla virtual (subconsulta) como esta con ejemplos numerados. (Este es un dolor en MySQL, y algunos otros DBMS caros hacen que sea más fácil No importa..)
SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
FROM (
SELECT entry_time, value
FROM table
ORDER BY entry_time
) C,
(SELECT @sample:=0) s
Esta pequeña tabla virtual da entry_num, entry_time, valor.
El próximo paso, lo unimos a sí mismo.
SELECT one.entry_num, one.entry_time, one.value,
TIMEDIFF(two.value, one.value) interval
FROM (
/* virtual table */
) ONE
JOIN (
/* same virtual table */
) TWO ON (TWO.entry_num - 1 = ONE.entry_num)
Esto concuerda las tablas siguientes dos entre sí compensado por una sola entrada, que se rige por la cláusula ON de la combinación.
Finalmente elegimos los valores de esta tabla con un interval
más grande que su umbral, y hay los tiempos de las muestras justo antes de los que faltan.
La consulta de autocombinación sobre todo es esto. Te dije que era una bola de pelo.
SELECT one.entry_num, one.entry_time, one.value,
TIMEDIFF(two.value, one.value) interval
FROM (
SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
FROM (
SELECT entry_time, value
FROM table
ORDER BY entry_time
) C,
(SELECT @sample:=0) s
) ONE
JOIN (
SELECT @sample2:[email protected]+1 AS entry_num, c.entry_time, c.value
FROM (
SELECT entry_time, value
FROM table
ORDER BY entry_time
) C,
(SELECT @sample2:=0) s
) TWO ON (TWO.entry_num - 1 = ONE.entry_num)
Si usted tiene que hacer esto en la producción en una mesa grande es posible que desee hacerlo para un subconjunto de los datos. Por ejemplo, puede hacerlo todos los días para las muestras de los dos días anteriores. Esto sería decentemente eficiente, y también se aseguraría de no omitir ninguna muestra faltante justo a la medianoche. Para hacer esto, sus pequeñas tablas virtuales redondas se verían así.
SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
FROM (
SELECT entry_time, value
FROM table
ORDER BY entry_time
WHERE entry_time >= CURRENT_DATE - INTERVAL 2 DAY
AND entry_time < CURRENT_DATE /*yesterday but not today*/
) C,
(SELECT @sample:=0) s
¿Cómo se define una brecha? ¿Tiene un límite estricto sobre cuánto tiempo puede transcurrir entre las entradas? –
Una variable Y. Olvidé especificar eso. – TheDog