Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie finde ich fehlende Datenzeilen mit 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'

Diese Abfrage gibt Couplets zurück, mit denen Sie die fehlenden Daten auswählen können. Die fehlenden Daten haben einen Zeitstempel zwischen hival und loval für jedes Couplet, das von der Abfrage zurückgegeben wird.

BEARBEITEN - danke fürs Prüfen, Craig

BEARBEITEN2 :

die fehlenden Zeitstempel erhalten - diese SQL wird etwas schwieriger zu lesen, also werde ich sie ein wenig aufschlüsseln. Zuerst brauchen wir eine Möglichkeit, eine Reihe von Zeitstempelwerten zwischen einem gegebenen niedrigen Wert und einem hohen Wert in 10-Minuten-Intervallen zu berechnen. Eine Möglichkeit, dies zu tun, wenn Sie keine Tabellen erstellen können, basiert auf der folgenden SQL, die als Ergebnismenge alle Ziffern von 0 bis 9 erstellt.

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

...indem wir nun diese Tabelle ein paar Mal mit einer Kopie von sich selbst kombinieren, können wir dynamisch eine Liste einer bestimmten Länge erzeugen

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

... jetzt nähert sich dieses Stück SQL dem, was wir brauchen. Es hat 2 Eingabevariablen:

  1. ein Startzeitstempel (im Beispiel habe ich curdate() verwendet); und ein
  2. Anzahl der Iterationen - die Where-Klausel gibt 42 Iterationen im Beispiel an, das Maximum bei 3-stelligen Tabellen sind 1000 Intervalle

... was bedeutet, dass wir die ursprüngliche SQL verwenden können, um das Beispiel von oben zu steuern, um eine Reihe von Zeitstempeln für jedes hivale Lowval-Paar zu generieren. Geduld mit mir, diese SQL ist jetzt ein bisschen lang ...

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

... jetzt gibt es ein bisschen episches SQL
HINWEIS:Wenn Sie die Zifferntabelle dreimal verwenden, ergibt sich eine maximale Lücke von etwas mehr als 6 Tagen