sql >> Databáze >  >> RDS >> Mysql

SQL – Najděte všechny doby výpadku a délky výpadků z dat MySQL (sada řádků s časovými razítky a stavovými zprávami)

Zde je jeden přístup.

Začněte seřazením stavových řádků podle časového razítka (vložené zobrazení s aliasem s ). Poté použijte uživatelské proměnné MySQL k uchování hodnot z předchozích řádků při zpracování každého řádku.

To, co skutečně hledáme, je stav „nahoře“, který bezprostředně následuje po sledu stavu „dolů“. A když najdeme tento řádek se stavem 'nahoře', skutečně potřebujeme nejstarší časové razítko z předchozí řady stavu 'dolů'.

Takže něco takového bude fungovat:

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

Toto funguje pro konkrétní soubor dat, který zobrazujete.

To, co toto nezpracovává (co nevrací), je období „dolů“, které ještě neskončilo, to znamená posloupnost stavu „dolů“ bez následujícího stavu „nahoru“.

Chcete-li se vyhnout operaci řazení souborů k vrácení řádků v pořadí, budete chtít krycí index na (time,status) . Tento dotaz vygeneruje dočasnou tabulku (MyISAM), která zhmotní vložený pohled s aliasem d .

POZNÁMKA: Abyste pochopili, co tento dotaz dělá, odloupněte tento nejvzdálenější dotaz a spusťte pouze dotaz pro vložené zobrazení s aliasem d (můžete přidat s.time do výběrového seznamu.)

Tento dotaz získává každý řádek se stavem „nahoru“ nebo „dolů“. "Trik" je v tom, že přiřazuje čas "začátek" i "konec" (označení období dolů) pouze řádkům, které končí období "dolů". (To znamená, že první řádek se stavem 'nahoru' po řádcích se stavem 'dolů'.) Zde se dělá skutečná práce, nejvzdálenější dotaz pouze odfiltruje všechny "nadbytečné" řádky v této sadě výsledků (že jsme nepotřebuji.)

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

Účel inline zobrazení s aliasem s je získat řádky seřazené podle hodnoty časového razítka, abychom je mohli zpracovat postupně. Vložený pohled s aliasem i je tam jen proto, abychom mohli inicializovat některé uživatelské proměnné na začátku dotazu.

Pokud bychom běželi na Oracle nebo SQL Server, mohli bychom využít „analytické funkce“ nebo „hodnotící funkce“ (jak se jmenují). MySQL nic takového neposkytuje, takže si musíme „vytvořit vlastní ".

."

  1. Plugin 'FEDERATED' je zakázán

  2. Jak opravit 'java.sql.SQLFeatureNotSupportedException' při použití metody createArrayOf()

  3. Vyberte z tabulky, kde pole neodpovídají podmínkám

  4. MySQL:Vložte, pokud tato IP nemá žádné záznamy