2012-07-20 71 views
3

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

我想知道一段时间(今天,本周,本月)警报设置为开启(武装= 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至0点29分58秒=> 19点58分钟武装。 从1:00:00到1:20:00布防=> 20分钟。为了这一天,警报已经持续了至少39:58分钟,这必须是我的查询结果。

日志就像一个心跳,所以警报可以在“开”和“关”状态之间进行布防,但我只想知道随后的行布防= 1。

我一直在为此而感到头疼。我自己加入了桌子,但我无法弄清楚如何做到这一点。它甚至有可能吗? 我已经设置了一个SQL小提琴玩数据:http://sqlfiddle.com/#!2/9eca2/2/0

谢谢。

回答

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; 
+0

谢谢您的查询。它确实给出了一个有趣的结果。我更新了SQL小提琴:http://sqlfiddle.com/#!2/9eca2/26 从这个查询中获得总数(39:58)仍然很困难。你不能只计算/总结'时间'值的总和。是否有可能在纯SQL中获得结果? – user1540127 2012-07-26 06:57:31

+0

我更新了新的查询,只是尝试它。它会给你准确的结果为39:58 – Omesh 2012-07-26 09:23:31

+0

这似乎很棒。编辑/尝试它时我犯了错误吗?在SQL小提琴它给我1:19:56:http://sqlfiddle.com/#!2/9eca2/37 我只更改列'adate'到日期以匹配表中的列。 非常感谢您的帮助。 :) – user1540127 2012-07-26 16:10:52