2011-11-07 29 views
1

特定の親レコードのステータス履歴を含む子テーブルがあります。複数行の時間差を計算して合計する

表は次のようになります。

Parent_id NUMBER(38) 
Date_Created DATE 
Status VARCHAR2(15) 

サンプルデータ:

1, sysdate-20, REQ 
1, sysdate-10, INPRG 
1, sysdate-5, WAIT 
1, sysdate-2, INPRG 
1, sysdate, COMP 

いずれかの特定のPARENT_IDについて、どのように私は、PARENT_IDが特定のステータスにとどまった合計時間を計算することができますか?次のステータスが作成された日付が計算された場合、日付レコードが作成されました。ステータスは複数回発生する可能性があることに注意してください。

サンプルデータについては、レコードが「INPRG」状態になった合計時間をどのように計算できましたか?

Oracle SQLですべて実行する必要があります。機能、手順、パッケージなどはありません。

ありがとうございます。

+0

ありがとうございます!それはうまくいった。 –

答えて

1

私は主にSQL Serverのではなく、Oracleを使用するので、私の構文は少しオフであれば、私を許して...

with base as (
    select Parent_id, Date_Created, Status, 
    row_number() over(partition by Parent_id order by Date_Created) as 'row' 
    from Table 
) 
select Parent_id, Status, sum(timeInStatus) 
from (
    select this.Parent_id, this.Status, 
    next.Date_Created-this.Date_Created as 'timeInStatus' 
    from base this 
    join base next on this.Parent_id=next.Parent_id 
        and this.row=next.row-1 
) t 
where Status = 'INPRG' 
group by Parent_id, Status 

基本row_numberを利用して、各行を次の行に自己結合し、それらの間の時間を計算することです。そして、それはあなたが望む答えを得るためのデータの単純な集約です。

3

解析関数LEADおよびLAGを使用して、結果セット内の次の行または前の行のデータにアクセスできます。このような何か

あなたに、各状態の合計時間を与えるだろう
SQL> ed 
Wrote file afiedt.buf 

    1 with t as (
    2 select 1 parent_id, sysdate-20 date_created, 'REQ' status from dual 
    3 union all 
    4 select 1, sysdate-10, 'INPRG' from dual 
    5 union all 
    6 select 1, sysdate-5, 'WAIT' from dual 
    7 union all 
    8 select 1, sysdate-2, 'INPRG' from dual 
    9 union all 
10 select 1, sysdate, 'COMP' from dual 
11 ) 
12 select parent_id, 
13   status, 
14   sum(time_in_status) 
15 from (
16  select parent_id, 
17    date_created, 
18    nvl(lead(date_created) over 
19       (partition by parent_id 
20        order by date_created), 
21     sysdate) next_status_date, 
22    nvl(lead(date_created) over 
23       (partition by parent_id 
24        order by date_created), 
25     sysdate) - 
26    date_created time_in_status, 
27    status 
28  from t) 
29* group by parent_id, status 
SQL>/

PARENT_ID STATU SUM(TIME_IN_STATUS) 
---------- ----- ------------------- 
     1 REQ     10 
     1 COMP     0 
     1 WAIT     3 
     1 INPRG     7