我在Oracle 11g数据库中有一个类似于以下内容的表:
process_times:
--------------------------------------------
machine_id | load_id | start_time | end_time
一些示例记录可能如下所示:
process_times:
----------------------------------------------------------------
machine_id | load_id | start_time | end_time
----------------------------------------------------------------
220 | 25 | 06/24/2012 04:29:00 | 06/25/2012 04:42:38
187 | 23 | 06/22/2012 14:41:00 | 06/24/2012 00:34:32
187 | 18 | 06/20/2012 11:57:00 | 06/20/2012 23:53:51
我正在尝试编写一个查询,该查询将返回与表示每台计算机的加载之间的停机时间的属性的关系。停机时间是指给定机器的每个end_time和后续start_time之间的时间。
因此,对于上面的例子,我得到的结果如下:
result:
----------------------
machine_id | down_time
----------------------
220 | 0
187 | (06/22/2012 14:41:00 - 06/20/2012 23:53:51) -- the actual result, I wrote it like this to be more clear
我一直在修补下午的一大部分,这只是我真正想写的查询的先决条件所以我想我会发帖看看是否有人有任何指示让我前进在正确的方向。
编辑我应该提到的另一个限制是,我需要让结果列表包含每台机器的单独停机时间,而不仅仅是给定时间段内停机时间的总量。
答案 0 :(得分:2)
有趣的问题。您需要先获取上一个/下一个记录然后进行减法。幸运的是,Oracle具有前导/滞后功能。
所以:
select machine_id, (lastend - start_time) as down_time
from (select pt.*,
lag(end_time, 1) over (partition by machine_id order by end_time) as lastend
from process_time pt
) pt
where lastend is not null
这会找到前一个记录和结束时间,然后计算停机时间。
答案 1 :(得分:1)
这未经过测试,但根据我的评论,这可以让你获得正常运行时间。如果您知道总时间窗口,则可以从正常运行时间轻松获得停机时间。
SELECT machine_id, SUM(joblen) AS uptime
FROM (
SELECT machine_id, (end_time - start_time) AS joblen
FROM process_times
)
GROUP BY machine_id
事实上,子查询甚至可能不是必需的,你可以做类似
的事情SELECT machine_id, SUM(end_time - start_time) AS uptime
FROM process_times
GROUP BY machine_id
我不知道。
从那里,您可以执行以下操作:
SELECT machine_id, (lifetime - uptime) AS downtime
FROM (
SELECT machine_id,
SUM(end_time - start_time) AS uptime,
(min(start_time) - max(end_time) as lifetime
FROM process_times
GROUP BY machine_id
)
无论如何,这是我如何接近它的大致轮廓,几乎肯定不会是剪切和粘贴类型的答案。