SQL如何计算自某些状态以来已经过了多少个月

时间:2015-10-14 11:53:15

标签: sql oracle status lag

我有一个包含项目,期间和状态及其周期值的表格。我的目标是显示自某个项目最后进入“已批准状态”以来已经过了多少个月。 (或显示此状态已更改的时间段)在period_leaving_approved_status列中。例如,对于201005到201008期间 - 我需要显示' 201005'价值,但对于201011-201012期间 - ' 201011'值。我设法标记状态更改的行,但我不知道如何应用以下行的条件。我的示例查询:

with subq as (
select 123 as project,  201002 as period,   'Approved' as status from dual
union all
select 123 as project,  201003 as period,   'Approved' as status from dual
union all
select 123 as project,  201004 as period,   'Approved' as status from dual
union all
select 123 as project,  201005 as period,   'Pending Close' as status from dual
union all
select 123 as project,  201006 as period,   'Pending Close' as status from dual
union all
select 123 as project,  201007 as period,   'Closed' as status from dual
union all
select 123 as project,  201008 as period,   'Closed' as status from dual
union all
select 123 as project,  201009 as period,   'Approved' as status from dual
union all
select 123 as project,  201010 as period,   'Approved' as status from dual
union all
select 123 as project,  201011 as period,   'Closed' as status from dual
union all
select 123 as project,  201012 as period,   'Closed' as status from dual
union all
select 123 as project,  201101 as period,   'Approved' as status from dual
union all
select 123 as project,  201102 as period,   'Approved' as status from dual
union all
select 123 as project,  201112 as period,   'Approved' as status from dual
union all
select 123 as project,  201301 as period,   'Pending Close' as status from dual
union all
select 123 as project,  201302 as period,   'Closed' as status from dual
union all
select 123 as project,  201203 as period,   'Closed' as status from dual
)

select project, 
      period, 
      status,
      case when lag(status, 1, null) OVER (ORDER BY period)='Approved' 
      AND lag(status, 1, null) OVER (ORDER BY period) NOT IN(status) then period end as period_leaving_approved_status
      from subq

1 个答案:

答案 0 :(得分:0)

我会使用聚合来解决这个问题:

select project,
       max(case when status = 'Approved' then period end) as ApprovedPeriod
from subq;

如果你想要时间跨度,那么就像这样:

select project,
       months_between(max(case when status = 'Approved' then period end),
                      sysdate) as monthsSinceApproved,
       max(case when status = 'Approved' then period end) as ApprovedPeriod
from subq
group by project;

编辑:

如果您希望在所有行上累积此信息,请使用窗口函数:

select s.*,
       max(case when status = 'Approved' then period end) over
           (partition b project order by period) as LastApprovedPeriod
from subq s;