有这样一个设备状态历史表:
序列号ID|设备号|源状态|目标状态|目标状态开始时间|源状态开始时间
001 | A1 | RUN | WAIT |2012-8-1 23:30 |2012-8-1 08:30 |
002 | A1 | WAIT | IDLE |2012-8-2 10:30 |2012-8-1 23:30 |
003 | A1 | IDLE | RUN |2012-8-2 19:30 |2012-8-2 10:30 |
004 | A1 | RUN | IDLE |2012-8-3 12:30 |2012-8-2 19:30 |
005 | A2 | RUN | WAIT |2012-8-1 20:30 |2012-8-1 08:30 |
006 | A2 | WAIT | IDLE |2012-8-2 11:30 |2012-8-1 20:30 |
007 | A2 | IDLE | RUN |2012-8-2 18:30 |2012-8-2 11:30 |
008 | A2 | RUN | IDLE |2012-8-3 12:30 |2012-8-2 18:30 |
这个表的作用是这样,当一个设备的状态改变时,就会在这个表里面插入一条数据,
记录一下这个设备由什么状态改为什么状态。
其中表的“源状态开始时间”是等于对应的设备的上一个状态的“目标状态开始时间”
我的困难是:
现在需要查询:用户输入一段时间,例:2012-8-2 00:00至2012-9-4 00:00
在这段时间内,各个设备处在每一种状态下的时长。
难点:像A1这台设备,
最后的状态(目标状态)是IDLE,
这样状态的开始时间(目标状态开始时间)是:2012-8-3 12:30
也就是说A1这个设备从2012-8-3 12:30到现在都是处于IDLE状态。
那么A1处于IDLE状态的时间就应该是历史内统计的时间再加上从2012-8-3 12:30到现在的时间。
我怎么去组织这样的查询语句?
请高手指点迷津。
------解决方案--------------------
- SQL code
--给你补了一条数据进去,条件让我改成8月1日0点了,不然看着怪怪的。[SYS@myoracle] SQL>WITH T AS 2 (SELECT '001' ID, 3 'A1' NAME, 4 'RUN ' F_STATUS, 5 'WAIT' T_STATUS, 6 TO_DATE('2012-8-1 23:30', 'yyyy-mm-dd hh24:mi') T_TIME, 7 TO_DATE('2012-8-1 08:30', 'yyyy-mm-dd hh24:mi') F_TIME 8 FROM DUAL 9 UNION ALL 10 SELECT '002' ID, 11 'A1' NAME, 12 'WAIT' F_STATUS, 13 'IDLE' T_STATUS, 14 TO_DATE('2012-8-2 10:30', 'yyyy-mm-dd hh24:mi') T_TIME, 15 TO_DATE('2012-8-1 23:30', 'yyyy-mm-dd hh24:mi') F_TIME 16 FROM DUAL 17 UNION ALL 18 SELECT '003' ID, 19 'A1' NAME, 20 'IDLE' F_STATUS, 21 'RUN ' T_STATUS, 22 TO_DATE('2012-8-2 19:30', 'yyyy-mm-dd hh24:mi') T_TIME, 23 TO_DATE('2012-8-2 10:30', 'yyyy-mm-dd hh24:mi') F_TIME 24 FROM DUAL 25 UNION ALL 26 SELECT '004' ID, 27 'A1' NAME, 28 'RUN ' F_STATUS, 29 'IDLE' T_STATUS, 30 TO_DATE('2012-8-3 12:30', 'yyyy-mm-dd hh24:mi') T_TIME, 31 TO_DATE('2012-8-2 19:30', 'yyyy-mm-dd hh24:mi') F_TIME 32 FROM DUAL 33 UNION ALL 34 SELECT '005' ID, 35 'A2' NAME, 36 'RUN ' F_STATUS, 37 'WAIT' T_STATUS, 38 TO_DATE('2012-8-1 20:30', 'yyyy-mm-dd hh24:mi') T_TIME, 39 TO_DATE('2012-8-1 08:30', 'yyyy-mm-dd hh24:mi') F_TIME 40 FROM DUAL 41 UNION ALL 42 SELECT '006' ID, 43 'A2' NAME, 44 'WAIT' F_STATUS, 45 'IDLE' T_STATUS, 46 TO_DATE('2012-8-2 11:30', 'yyyy-mm-dd hh24:mi') T_TIME, 47 TO_DATE('2012-8-1 20:30', 'yyyy-mm-dd hh24:mi') F_TIME 48 FROM DUAL 49 UNION ALL 50 SELECT '007' ID, 51 'A2' NAME, 52 'IDLE' F_STATUS, 53 'RUN ' T_STATUS, 54 TO_DATE('2012-8-2 18:30', 'yyyy-mm-dd hh24:mi') T_TIME, 55 TO_DATE('2012-8-2 11:30', 'yyyy-mm-dd hh24:mi') F_TIME 56 FROM DUAL 57 UNION ALL 58 SELECT '008' ID, 59 'A2' NAME, 60 'RUN ' F_STATUS, 61 'IDLE' T_STATUS, 62 TO_DATE('2012-8-3 12:30', 'yyyy-mm-dd hh24:mi') T_TIME, 63 TO_DATE('2012-8-2 18:30', 'yyyy-mm-dd hh24:mi') F_TIME 64 FROM DUAL), 65 T2 AS 66 (SELECT ID, NAME, F_STATUS, T_STATUS, F_TIME, T_TIME 67 FROM T 68 UNION 69 SELECT TRIM(TO_CHAR(ID + 1, '099')), NAME, T_STATUS, '-', T_TIME, SYSDATE 70 FROM T 71 WHERE CONNECT_BY_ISLEAF = 1 72 CONNECT BY NOCYCLE PRIOR NAME = NAME 73 AND PRIOR T_TIME = F_TIME) 74 SELECT NAME, F_STATUS, SUM(T_TIME - F_TIME) 75 FROM T2 76 WHERE F_TIME BETWEEN TO_DATE('2012-8-1 00:00', 'yyyy-mm-dd hh24:mi') AND 77 TO_DATE('2012-9-4 00:00', 'yyyy-mm-dd hh24:mi') 78 GROUP BY NAME, F_STATUS 79 ORDER BY NAME;NA F_ST SUM(T_TIME-F_TIME)-- ---- ------------------A1 IDLE 33.5534028A1 RUN 1.33333333A1 WAIT .458333333A2 IDLE 33.4700694A2 RUN 1.25A2 WAIT .625已选择6行。[SYS@myoracle] SQL>