0

在数据库 MySQL 中,有一个表,其中包含有关从“问题”或“未知”到“正常”的对象的更改状态的信息:

CREATE TABLE `events` (
  `eventid` bigint(20) unsigned NOT NULL,
  `source` int(11) NOT NULL DEFAULT '0',
  `object` int(11) NOT NULL DEFAULT '0',
  `objectid` bigint(20) unsigned NOT NULL DEFAULT '0',
  `clock` int(11) NOT NULL DEFAULT '0',
  `value` int(11) NOT NULL DEFAULT '0',
  `acknowledged` int(11) NOT NULL DEFAULT '0',
  `ns` int(11) NOT NULL DEFAULT '0',
  `value_changed` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`eventid`),
  KEY `events_1` (`object`,`objectid`,`eventid`),
  KEY `events_2` (`clock`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


eventid | objectid | clock | value
77843   13619   1341588185  0
77859   13619   1341589085  2
77889   13619   1341590585  0
82174   13619   1341843065  2
82193   13619   1341843785  1
82197   13619   1341843965  0

其中,值 0 - 正常 1 - 问题,2 - 未知,时钟 - 时间(格式 unixtime)。

有一个查询可以计算指定时间的事件持续时间:

select a.eventid,a.objectid,a.`interval` from (
select
@prev_clock,
@prev_value,
l.*,
if(l.value='0' && @prev_value!='0' &&
@prev_objectid=l.objectid,TIMEDIFF(FROM_UNIXTIME(l.clock),FROM_UNIXTIME(@prev_clock)),null) 'interval',
(@prev_clock:=l.clock),(@prev_value:=l.value),(@prev_objectid:=l.objectid)
from events l,(select @vclock:=0,@prev_value:='',@prev_objectid:=0) b1
where l.clock>=1341588185 and objectid=13619
order by l.objectid,l.eventid
) a where a.value='0';

结果如下:

eventid objectid    interval
77843   13619   
77889   13619   00:25:00
82197   13619   00:03:00

帮助,根据以下条件更正查询/表达式:

1) 状态可以从 0 变为 1,然后是 2,然后再变为 1(如此多次).... 并且很久以后变为 0(例如,事件的持续时间 82 197 = 1341843965-1341843065 = 900秒而不是 180)。

2)在单元格的“间隔”中,不应有空值。

4

1 回答 1

2

你的意思是这样的:

SELECT e.eventid AS eventid_OK, errEvent.eventid AS eventid_ERROR, e.objectid, TIMEDIFF(FROM_UNIXTIME(e.clock),FROM_UNIXTIME(errEvent.clock)) 
FROM events AS e
INNER JOIN events AS errEvent 
    ON errEvent.clock = (SELECT MIN(err.clock) 
                         FROM events AS err 
                         WHERE err.objectid = e.objectid 
                         AND err.clock > (SELECT MAX(prev.clock) 
                                          FROM events AS prev 
                                          WHERE prev.objectid = e.objectid 
                                          AND prev.clock < e.clock 
                                          AND prev.value = 0) 
                         AND err.value IN (1,2)) 

WHERE e.value = 0

http://sqlfiddle.com/#!2/20354/3

于 2012-07-11T09:29:07.760 回答