查找停机时间并计算停机时间

时间:2019-05-03 17:37:13

标签: mysql

我的问题与此处的问题非常相似:SQL - Find all down times and the lengths of the downtimes from MySQL data (set of rows with time stamps and status messages)

我的代码全部正常工作。我有一个看起来像这样的数据集。我想计算状态为“ 0”的时间长度。

+---------------------+-------------+--------+
| created_at          | fk_check_id | status |
+---------------------+-------------+--------+
| 2019-05-03 08:35:22 |          12 |      0 |
| 2019-05-03 08:36:21 |          12 |      1 |
| 2019-05-03 08:37:21 |          12 |      1 |
| 2019-05-03 08:38:21 |          12 |      1 |
| 2019-05-03 08:39:21 |          12 |      0 |
| 2019-05-03 08:40:21 |          12 |      0 |
| 2019-05-03 08:41:21 |          12 |      1 |
| 2019-05-03 08:42:21 |          12 |      1 |
| 2019-05-03 08:43:21 |          12 |      1 |
| 2019-05-03 08:51:21 |          12 |      1 |
| 2019-05-03 08:52:21 |          12 |      1 |
| 2019-05-03 08:53:21 |          12 |      1 |
| 2019-05-03 08:54:21 |          12 |      0 |
| 2019-05-03 08:55:21 |          12 |      0 |
| 2019-05-03 08:56:22 |          12 |      1 |
| 2019-05-03 08:57:22 |          12 |      1 |
| 2019-05-03 09:01:21 |          12 |      1 |
| 2019-05-03 09:02:21 |          12 |      1 |
| 2019-05-03 09:03:21 |          12 |      0 |
| 2019-05-03 09:04:21 |          12 |      0 |
| 2019-05-03 09:05:22 |          12 |      0 |
| 2019-05-03 09:06:21 |          12 |      0 |
| 2019-05-03 09:07:21 |          12 |      0 |
| 2019-05-03 09:08:21 |          12 |      0 |
+---------------------+-------------+--------+

我的SQL查询如下:

  SELECT d.start_time
     , d.ended_time
  FROM (SELECT @i := @i + 1 AS i
             , @start := IF(s.status = '0' AND (@status = '1' OR @i = 1), s.created_at, @start) AS start_time
             , @ended := IF(s.status = '1' AND @status = '0', s.created_at, NULL) AS ended_time
             , @status := s.status
         FROM (SELECT t.created_at
                    , t.status
                 FROM logs t
                WHERE t.status IN ('1','0') AND fk_check_id=12
                ORDER BY t.created_at ASC, t.status ASC
              ) s
         JOIN (SELECT @i := 0, @status := '1', @ended := NULL, @start := NULL) i
      ) d
WHERE d.start_time IS NOT NULL
  AND d.ended_time IS NOT NULL

它返回如下结果:

Array
(
    [0] => Array
        (
            [start_time] => 2019-05-03 08:35:22
            [ended_time] => 2019-05-03 08:36:21
        )

    [1] => Array
        (
            [start_time] => 2019-05-03 08:39:21
            [ended_time] => 2019-05-03 08:41:21
        )

    [2] => Array
        (
            [start_time] => 2019-05-03 08:54:21
            [ended_time] => 2019-05-03 08:56:22
        )

)

一切正常,除了它没有返回最后一个“向下”块,因为还没有完整的“向上”条目。如何返回最新的行并将其用作我的“ ended_time”,直到输入完整的“ up”块?

我正在尝试计算总的停机时间,并且由于尚未列出最后一个条目,因此我的结果出现了偏差。

谢谢!

1 个答案:

答案 0 :(得分:0)

您正在使用哪个版本的MySQL?如果您使用的是MySQL 8,则可能会用以下内容替换当前结束的选择:

, @ended := IF((s.status = '1' OR (s.created_at = MAX(s.created_at) OVER())) AND @status = '0', s.created_at, NULL) AS ended_time

如果您不使用MySQL 8,这将无济于事。 MySQL 8引入了OVER()函数。