计算多组数据之间的时间差

时间:2016-07-07 11:06:18

标签: mysql sql

这是mysql表中的数据集,它与电子设备的错误日志有关。 我需要计算总停机时间。

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

如何编写与mySQL兼容的SQL语句来实现此目的。

2 个答案:

答案 0 :(得分:0)

使用此功能,您将得到总数

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

----------例如----

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 |

答案 1 :(得分:0)

基本上,您需要计算已发生的累积错误的数量。然后识别值大于0的组。这可以通过对累积错误执行累计计数“0”来完成。

获得最终时间戳是一项挑战。一个技巧是获取错误的下一个状态0时间戳。这充当了“结束”。

最后,汇总获取每个时期的信息:

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;

您可以对此查询进行汇总,以获得停机总时间。

Here是一个SQL小提琴。