我有一个子表,其中包含特定父记录的状态历史记录。
表格如下:
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 :(得分: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
答案 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
将每一行自我连接到它的下一行并计算它们之间的时间。然后,它只是一个简单的数据汇总,以获得您想要的答案。