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

¿Cómo encontrar filas de datos faltantes usando SQL?

select t1.ts as hival, t2.ts as loval
from metdata t1, metdata t2
where t2.ts = (select max(ts) from metdata t3
where t3.ts < t1.ts)
and not timediff(t1.ts, t2.ts) = '00:10:00'

Esta consulta devolverá coplas que puede usar para seleccionar los datos que faltan. Los datos faltantes tendrán una marca de tiempo entre hival y loval para cada pareado devuelto por la consulta.

EDITAR - gracias por verificar, Craig

EDITAR2:

obtener las marcas de tiempo que faltan:este SQL se vuelve un poco más difícil de leer, así que lo dividiré un poco. Primero, necesitamos una forma de calcular una serie de valores de marca de tiempo entre un valor bajo dado y un valor alto en intervalos de 10 minutos. Una forma de hacer esto cuando no puede crear tablas se basa en el siguiente sql, que crea como resultado todos los dígitos del 0 al 9.

select d1.* from 
(select 1 as digit
union select 2 
union select 3 
union select 4 
union select 5 
union select 6 
union select 7 
union select 8 
union select 9 
union select 0 
) as d1

... ahora, al combinar esta tabla con una copia de sí misma un par de veces, podemos generar dinámicamente una lista de una longitud específica

select curdate() + 
INTERVAL  (d1.digit * 100 + d2.digit * 10 + d3.digit) * 10 MINUTE 
as date 
from (select 1 as digit
union select 2 
union select 3 
union select 4 
union select 5 
union select 6 
union select 7 
union select 8 
union select 9 
union select 0 
) as d1
join
(select 1 as digit
union select 2 
union select 3 
union select 4 
union select 5 
union select 6 
union select 7 
union select 8 
union select 9 
union select 0 
) as d2
join
(select 1 as digit
union select 2 
union select 3 
union select 4 
union select 5 
union select 6 
union select 7 
union select 8 
union select 9 
union select 0 
) as d3
where (d1.digit * 100 + d2.digit * 10 + d3.digit) between 1 and 42
order by 1

... ahora esta pieza de sql se está acercando a lo que necesitamos. Tiene 2 variables de entrada:

  1. una marca de tiempo de inicio (utilicé curdate() en el ejemplo); y un
  2. número de iteraciones:la cláusula where especifica 42 iteraciones en el ejemplo, el máximo con tablas de 3 x dígitos es de 1000 intervalos

... lo que significa que podemos usar el sql original para impulsar el ejemplo de arriba para generar una serie de marcas de tiempo para cada par hival lowval. Ten paciencia conmigo, este sql es un poco largo ahora...

select daterange.loval + INTERVAL  (d1.digit * 100 + d2.digit * 10 + d3.digit) * 10 MINUTE as date 
from 
(select t1.ts as hival, t2.ts as loval
from metdata t1, metdata t2
where t2.ts = (select max(ts) from metdata t3
where t3.ts < t1.ts)
and not timediff(t1.ts, t2.ts) = '00:10:00'
) as daterange
join
(select 1 as digit
union select 2 
union select 3 
union select 4 
union select 5 
union select 6 
union select 7 
union select 8 
union select 9 
union select 0 
) as d1
join
(select 1 as digit
union select 2 
union select 3 
union select 4 
union select 5 
union select 6 
union select 7 
union select 8 
union select 9 
union select 0 
) as d2
join
(select 1 as digit
union select 2 
union select 3 
union select 4 
union select 5 
union select 6 
union select 7 
union select 8 
union select 9 
union select 0 
) as d3
where (d1.digit * 100 + d2.digit * 10 + d3.digit) between 1 and
 round((time_to_sec(timediff(hival, loval))-600) /600)
order by 1

...ahora hay un poco de sql épico
NOTA:usar la tabla de dígitos 3 veces da una brecha máxima que cubrirá un poco más de 6 días