3

假设我有一个带有警报系统日志的数据库。有一个间隔,在数据库中插入一个新行。该行有alarm_id、一个日期时间和一个警报是打开还是关闭的标志。

我想知道在一段时间(今天、本周、本月)内警报设置为开启(armed=1)多长时间。这将是具有武装=1 的后续行。如果有一个武装=0 的行,它可能不会被计算在内。

例如:

id      alarm_id        armed       date        
1       1               0           2012-01-01 00:00:00
2       1               1           2012-01-01 00:10:00
3       1               1           2012-01-01 00:20:10
4       1               1           2012-01-01 00:29:58
5       1               0           2012-01-01 00:40:00
6       1               1           2012-01-01 01:00:00
7       1               1           2012-01-01 01:10:00
8       1               1           2012-01-01 01:20:00
9       1               0           2012-01-01 01:30:00

在本例中,警报从 00:10:00 到 00:29:58 => 19:58 分钟布防。从 1:00:00 到 1:20:00 => 20 分钟布防。在这一天,警报已经启动至少 39:58 分钟,这必须是我查询的结果。

日志就像一个心跳,因此警报可以在“开”和“关”状态之间进行武装,但我只想知道后续行武装=1。

我一直在为此烦恼。我自己加入了桌子,但我不知道该怎么做。甚至可能吗?我已经设置了一个 SQL Fiddle 来处理数据:http ://sqlfiddle.com/#!2/9eca2/2/0

谢谢。

4

1 回答 1

2

您将不得不使用类似这样的东西在 MySQL 中使用单个查询来执行此操作:

SELECT armed_at INTO @v FROM alarm ORDER BY armed_at LIMIT 1;

SELECT armed, TIMEDIFF(armed_at, @v), @v:=armed_at FROM alarm;

有关更多详细信息,请尝试:

SET @t =0;
SELECT armed_at INTO @v FROM alarm ORDER BY armed_at LIMIT 1;
SELECT armed, 
       IF(armed = 1, @t:=ADDTIME(TIME(TIMEDIFF(armed_at, IF(@v <> 0, @v, armed_at))), @t) , @t:=0) AS time, 
       IF(armed = 1, @v:=armed_at, @v := 0) AS v 
FROM alarm;

更新后的查询将为您提供所需的确切结果,请尝试:

SET @a=0, @d=0, @t=0;

SELECT atime
FROM (
      SELECT id, armed,
             IF((@a = 1 AND armed = 1), @t:=ADDTIME(TIME(TIMEDIFF(adate, IF(@d <> 0, @d, adate))), @t) , 0) AS atime,
             IF((@a:=armed) = 1, @d:=adate, @d := 0) AS d
      FROM alarmlog
     ) a
WHERE a.armed = 1
ORDER BY id DESC
LIMIT  1;
于 2012-07-20T09:17:21.477 回答