2012-06-25 97 views
0

我在Oracle 11g數據庫中有一個表,它是類似以下內容:尋找球幫助構造SQL查詢

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

您使用的數據庫是? – Oded

+0

@已更新數據庫〜對不起! – user12345613

+0

我認爲通過簡單地查找行時間增量來計算「正常運行時間」會比較容易,然後從總時間中減去它(這可能類似'min(start_time) - max(end_time)') – jedwards

回答

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 

此找到與以前的記錄時間和結束時間,然後計算的停機時間。

+0

這個是美麗的。我認爲這可能奏效 - 我必須從我簡化的例子中將它翻譯回真正的交易,看看它是否有效,但無論哪種方式,都要感謝展示有關領先/滯後。 – user12345613

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 
    ) 

無論如何,這是我怎麼想靠近它一個大致的輪廓,它幾乎肯定不會是一個剪切和粘貼式的回答。

+0

這是一個非常好的方法來解決這個問題 - 不幸的是我需要保持停機時間,以便客戶可以查看機器在兩次使用之間空閒的時間。我會更新這個問題來澄清。 – user12345613