计算并计算多行之间的时差

时间:2011-11-07 21:12:17

标签: sql oracle oracle10g

我有一个子表,其中包含特定父记录的状态历史记录。

表格如下:

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中完成。没有功能,程序,包等。

提前致谢。

2 个答案:

答案 0 :(得分:3)

您可以使用分析函数LEADLAG来访问结果集中下一行或上一行的数据。这样的事情会给你每个状态的总时间

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

答案 1 :(得分: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将每一行自我连接到它的下一行并计算它们之间的时间。然后,它只是一个简单的数据汇总,以获得您想要的答案。