我的问题与此处的问题非常相似: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”块?
我正在尝试计算总的停机时间,并且由于尚未列出最后一个条目,因此我的结果出现了偏差。
谢谢!
答案 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()函数。