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

SQL - Znajdź wszystkie czasy przestojów i długości przestojów z danych MySQL (zestaw wierszy ze znacznikami czasu i komunikatami o stanie)

Oto jedno podejście.

Zacznij od uporządkowania wierszy stanu według sygnatury czasowej (widok wbudowany z aliasem s ). Następnie użyj zmiennych użytkownika MySQL, aby zachować wartości z poprzednich wierszy podczas przetwarzania każdego wiersza.

To, czego naprawdę szukamy, to status „w górę”, który natychmiast następuje po sekwencji stanów „w dół”. A kiedy znajdziemy wiersz ze stanem „w górę”, naprawdę potrzebujemy najwcześniejszego znacznika czasu z poprzedniej serii stanu „w dół”.

Tak więc zadziała coś takiego:

SELECT d.start_down
     , d.ended_down
  FROM (SELECT @i := @i + 1 AS i
             , @start := IF(s.status = 'down' AND (@status = 'up' OR @i = 1), s.time, @start) AS start_down
             , @ended := IF(s.status = 'up' AND @status = 'down', s.time, NULL) AS ended_down
             , @status := s.status
         FROM (SELECT t.time
                    , t.status
                 FROM mydata t
                WHERE t.status IN ('up','down')
                ORDER BY t.time ASC, t.status ASC
              ) s
         JOIN (SELECT @i := 0, @status := 'up', @ended := NULL, @start := NULL) i
      ) d
WHERE d.start_down IS NOT NULL
  AND d.ended_down IS NOT NULL

Działa to dla konkretnego wyświetlanego zestawu danych.

To, czego to nie obsługuje (czego nie zwraca), to okres „nieaktywny”, który jeszcze się nie zakończył, to znaczy sekwencja statusu „nie działa” bez następującego statusu „w górę”.

Aby uniknąć operacji sortowania plików, która zwraca wiersze w kolejności, będziesz potrzebować indeksu obejmującego (time,status) . To zapytanie wygeneruje tymczasową tabelę (MyISAM), aby zmaterializować widok wbudowany aliasem d .

UWAGA: Aby zrozumieć, co robi to zapytanie, oderwij to najbardziej zewnętrzne zapytanie i uruchom tylko zapytanie dla widoku wbudowanego o aliasie d (możesz dodać s.time do listy wyboru.)

To zapytanie pobiera każdy wiersz ze statusem „w górę” lub „w dół”. „Sztuczka” polega na tym, że przypisuje zarówno czas „początku”, jak i „zakończenia” (oznaczenie okresu spadku) tylko w wierszach, które kończą okres „w dół”. (Oznacza to, że pierwszy wiersz ze statusem „w górę” następujący po wierszach ze statusem „w dół”.) W tym miejscu wykonywana jest prawdziwa praca, najbardziej zewnętrzne zapytanie po prostu odfiltrowuje wszystkie „dodatkowe” wiersze w tym zestawie wyników (które nie trzeba.)

SELECT @i := @i + 1 AS i
     , @start := IF(s.status = 'down' AND (@status = 'up' OR @i = 1), s.time, @start) AS start_down
     , @ended := IF(s.status = 'up' AND @status = 'down', s.time, NULL) AS ended_down
     , @status := s.status
     , s.time
  FROM (SELECT t.time
             , t.status
          FROM mydata t
         WHERE t.status IN ('up','down')
         ORDER BY t.time ASC, t.status ASC
       ) s
  JOIN (SELECT @i := 0, @status := 'up', @ended := NULL, @start := NULL) i

Przeznaczenie wbudowanego widoku aliasowanego jako s jest uzyskanie wierszy uporządkowanych według wartości znacznika czasu, abyśmy mogli przetwarzać je po kolei. Widok wbudowany aliasem i jest tylko tam, abyśmy mogli zainicjować niektóre zmienne użytkownika na początku zapytania.

Gdybyśmy pracowali na Oracle lub SQL Server, moglibyśmy skorzystać z „funkcji analitycznych” lub „funkcji rankingowych” (jak się je nazywa). MySQL nie zapewnia niczego takiego, więc musimy „zrobić własne ".



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wykonaj polecenie mysql przed testem skryptu na GitLab CI

  2. Data wygaśnięcia jako wartość domyślna dla kolumny TIMESTAMP

  3. php7.4 mysqli przestaje działać i odchodzi

  4. Przekonwertować zrzut SQL na JSON?

  5. Elementy sum MySql w kolumnie