2016-07-07 15 views
1

Dies ist ein Datensatz in einer MySQL-Tabelle, der sich auf ein Fehlerprotokoll eines elektronischen Geräts bezieht. Ich muss die Gesamtausfallzeit berechnen.Zeitunterschiede zwischen mehreren Datensätzen berechnen

time_stamp  error_type error_status 
1467820110   1   1 
1467820120   2   1     
1467820130   3   1 
1467820140   3   0 
1467820150   1   0 
1467820160   2   0 
1467820180   1   1 
1467820185   1   0 
1467820191   2   1 
1467820300   2   0 
1467820302   1   1 
1467820404   3   1 
1467820408   3   0 
1467820409   1   0 

error_status 1 = error occored 
error_status 0 = error fixed 

1st down time 1467820160 - 1467820110 = 50 
2nd down time 1467820185 - 1467820180 = 5 
3rd down time 1467820300 - 1467820191 = 109 
4th down time 1467820409 - 1467820302 = 107 

total down time = 50 + 5 + 109 + 107 = 271 

Wie kann ich eine mySQL-kompatible SQL-Anweisung schreiben, um dies zu erreichen.

+0

was ist die Beziehung Lieferung mit Fehlertyp und Gesamtwert –

+0

@Kevin - können Sie bitte die erstellen und fügt für die Probe –

+0

@MaheshMadushanka nur die Summe unabhängig von der Art des Fehlers. – Kevin

Antwort

0

Grundsätzlich müssen Sie die Anzahl der kumulativen berechnen Fehler, die aufgetreten sind. Identifizieren Sie dann Gruppen, deren Werte größer als 0 sind. Dies kann durch eine kumulative Zählung der Anzahl der "0" für die kumulativen Fehler erfolgen.

Es gibt eine Herausforderung, den letzten Zeitstempel zu bekommen. Ein Trick besteht darin, den nächsten Status 0 Zeitstempel für den Fehler zu erhalten. Dies wirkt als ein "Ende".

Schließlich erhalten eine Aggregation die Informationen für jede Periode:

select count(*) as num_errors, max(end_timestamp) - min(timestamp) 
from (select t.*, 
      (@grp := @grp + if(cume_errors = 0, 1, 0)) as grp 
     from (select t.*, 
        (select t2.timestamp 
        from t t2 
        where t2.error_type = t.error_type and 
          t2.error_status = 0 and 
          t2.timestamp > t.timestamp 
        order by t2.timestamp asc 
        limit 1 
        ) as end_timestamp, 
        (@e := @e + if(error_status > 0, 1, -1)) as cume_errors 
      from t cross join 
       (select @e := 0) params 
      order by timestamp 
      ) t cross join 
      (select @grp := 0) params 
     order by timestamp 
    ) t 
where error_status > 0 
group by grp; 

Sie können diese Abfrage aggregieren über die Gesamtausfallzeit zu erhalten.

Here ist eine SQL-Fiddle.

0

diese Anwendung werden Sie die Gesamt

SELECT sum(IF(error_status=1,time_stamp*-1,time_stamp)) as total FROM table; 

---------- Beispiel bekommen ----

mysql> SELECT sum(IF(error_status=1,time_stamp*-1,time_stamp)) as total FROM hh; 
+-------+ 
| total | 
+-------+ 
| 315 | 
+-------+ 
1 row in set (0.06 sec) 

mysql> SELECT *,(IF(error_status=1,time_stamp*-1,time_stamp)) as total FROM hh; 
+------------+------------+--------------+-------------+ 
| time_stamp | error_type | error_status | total  | 
+------------+------------+--------------+-------------+ 
| 1467820110 |   1 |   1 | -1467820110 | 
| 1467820120 |   2 |   1 | -1467820120 | 
| 1467820130 |   3 |   1 | -1467820130 | 
| 1467820140 |   3 |   0 | 1467820140 | 
| 1467820150 |   1 |   0 | 1467820150 | 
| 1467820160 |   2 |   0 | 1467820160 | 
| 1467820180 |   1 |   1 | -1467820180 | 
| 1467820185 |   1 |   0 | 1467820185 | 
| 1467820191 |   2 |   1 | -1467820191 | 
| 1467820300 |   2 |   0 | 1467820300 | 
| 1467820302 |   1 |   1 | -1467820302 | 
| 1467820404 |   3 |   1 | -1467820404 | 
| 1467820408 |   3 |   0 | 1467820408 | 
| 1467820409 |   1 |   0 | 1467820409 | 
+0

Die Logik ist korrekt, wenn ein einzelner Fehlertyp berücksichtigt wird. Es können jedoch verschiedene Fehler gleichzeitig auftreten. – Kevin

+0

@Kevin: aber immer noch wird dies korrekt sein, wenn Sie Fehler Startzeit haben sollte es Fehler behoben Zeit und dies wird Zeit difference –

+0

können Sie vorschlagen, alle Datensätze, die über Logik –

Verwandte Themen