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

Metoda hledání mezer v datech časových řad v MySQL?

Pro začátek shrňme počet záznamů podle hodin ve vaší tabulce.

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

Nyní, pokud něco zaznamenáte každých šest minut (desetkrát za hodinu), všechny vaše hodnoty samplecount by měly být deset. Tento výraz:CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) vypadá chlupatě, ale jednoduše zkrátí vaše časová razítka na hodinu, ve které se vyskytují, vynulováním minuty a sekundy.

To je přiměřeně efektivní a pomůže vám to začít. Je velmi efektivní, pokud můžete umístit index do sloupce entry_time a omezit svůj dotaz na, řekněme, včerejší vzorky, jak je uvedeno zde.

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 WHERE entry_time >= CURRENT_DATE - INTERVAL 1 DAY
   AND entry_time < CURRENT_DATE
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

Ale není to moc dobré na odhalování celých hodin, které uplynou s chybějícími vzorky. Je také trochu citlivý na chvění při vzorkování. To znamená, že pokud je váš vzorek nejvyšší hodiny někdy o půl sekundy dříve (10:59:30) a někdy o půl sekundy později (11:00:30), vaše hodinové souhrnné počty budou vypnuté. Takže tento hodinový souhrn (nebo shrnutí dne, nebo minutový souhrn atd.) není neprůstřelný.

Chcete-li, aby byly věci dokonale správné, potřebujete dotaz na vlastní spojení; je to trochu více chlupáče a není zdaleka tak účinné.

Začněme tím, že si vytvoříme virtuální tabulku (poddotaz) takto s očíslovanými vzorky. (To je problém MySQL; některé jiné drahé DBMS to usnadňují. Nevadí.)

  SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
    ) C,
    (SELECT @sample:=0) s

Tato malá virtuální tabulka poskytuje entry_num, entry_time, value.

V dalším kroku jej připojíme k sobě.

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
     /* virtual table */
  ) ONE
  JOIN (
     /* same virtual table */
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

Tím se seřadí další dvě tabulky navzájem posunuté o jeden záznam, který se řídí klauzulí ON v JOIN.

Nakonec vybereme hodnoty z této tabulky s interval větší než váš práh a před chybějícími jsou časy vzorků.

Celkový dotaz na samostatné připojení je tento. Řekl jsem ti, že to byla koule na vlasy.

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
    SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample:=0) s
  ) ONE
  JOIN (
    SELECT @sample2:[email protected]+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample2:=0) s
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

Pokud to musíte udělat v produkci na velké tabulce, možná to budete chtít udělat pro podmnožinu vašich dat. Můžete to například udělat každý den pro vzorky z předchozích dvou dnů. To by bylo slušně efektivní a také by to zajistilo, že hned o půlnoci nepřehlédnete žádné chybějící vzorky. Chcete-li to provést, vaše malé virtuální stoly s čísly řádků by vypadaly takto.

  SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
         WHERE entry_time >= CURRENT_DATE - INTERVAL 2 DAY
           AND entry_time < CURRENT_DATE /*yesterday but not today*/
    ) C,
    (SELECT @sample:=0) s


  1. Instalace MariaDB 10.1 v Debian Jessie a spouštění různých dotazů MariaDB

  2. Jak funguje SQLite Avg()

  3. Strange MySQL Popup Mysql Installer běží v komunitním režimu

  4. Rozdíl v požadovaném čase pro vložení záznamů InnoDB/MyISAM