Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak znaleźć brakujące wiersze danych za pomocą 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'

To zapytanie zwróci kuplety, których możesz użyć do wybrania brakujących danych. Brakujące dane będą miały sygnaturę czasową między hival i loval dla każdego dwuwiersza zwróconego przez zapytanie.

EDIT - dzięki za sprawdzenie, Craig

EDYCJA2:

pobranie brakujących znaczników czasu — ten kod SQL staje się nieco trudniejszy do odczytania, więc trochę go podzielę. Po pierwsze, potrzebujemy sposobu na obliczenie serii wartości znaczników czasu między daną niską a wysoką wartością w odstępach 10-minutowych. Sposobem na zrobienie tego, gdy nie możesz tworzyć tabel, jest następujący sql, który tworzy jako zbiór wyników wszystkie cyfry od 0 do 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

...teraz łącząc tę ​​tabelę z kopią jej kilka razy, możemy dynamicznie generować listę o określonej długości

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

... teraz ten fragment sql zbliża się do tego, czego potrzebujemy. Ma 2 zmienne wejściowe:

  1. początkowy znacznik czasu (w przykładzie użyłem curdate()); i
  2. liczba iteracji - klauzula gdzie określa 42 iteracje w przykładzie, maksymalnie przy 3 x cyfrowych tabelach jest 1000 interwałów

... co oznacza, że ​​możemy użyć oryginalnego sql do prowadzenia powyższego przykładu w celu wygenerowania serii znaczników czasu dla każdej pary hival lowval. Wytrzymaj, ten sql jest teraz trochę długi...

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

...teraz jest trochę epickiego sql
UWAGA:użycie tablicy cyfr 3 razy daje maksymalną lukę, którą pokryje nieco ponad 6 dni



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dlaczego tworzenie klucza obcego w Laravel 5.8 kończy się niepowodzeniem?

  2. MySQL przy usuwaniu kaskadowym. Przykład testowy

  3. Jak grupować według miesięcy w MySQL

  4. Odejmij miesiąc i dzień mysql

  5. Wybieranie danych z mySQL za pomocą identyfikatora w adresie URL