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

Come trovare le righe di dati mancanti 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'

Questa query restituirà distici che puoi utilizzare per selezionare i dati mancanti. I dati mancanti avranno un timestamp tra hival e loval per ogni distico restituito dalla query.

EDIT - grazie per il controllo, Craig

EDIT2 :

ottenere i timestamp mancanti:questo SQL diventa un po 'più difficile da leggere, quindi lo spezzerò un po'. Innanzitutto, abbiamo bisogno di un modo per calcolare una serie di valori di timestamp tra un dato valore basso e un valore alto in intervalli di 10 minuti. Un modo per farlo quando non puoi creare tabelle si basa sul seguente sql, che crea come set di risultati tutte le cifre da 0 a 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

...ora combinando questa tabella con una copia di se stessa un paio di volte significa che possiamo generare dinamicamente un elenco di una lunghezza specificata

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

... ora questo pezzo di sql si sta avvicinando a ciò di cui abbiamo bisogno. Dispone di 2 variabili di input:

  1. un timestamp di inizio (ho usatocurdate() nell'esempio); e un
  2. numero di iterazioni - la clausola where specifica 42 iterazioni nell'esempio, il massimo con tabelle di 3 x cifre è 1000 intervalli

... il che significa che possiamo usare l'originale sql per guidare l'esempio dall'alto per generare una serie di timestamp per ogni coppia hival lowval. Abbi pazienza, questo sql è un po' lungo adesso...

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

...ora c'è un po' di sql epico
NOTA:usando la tabella delle cifre 3 volte si ottiene un gap massimo che coprirà di poco più di 6 giorni