我需要分析存储在一个Oracle数据库表中的一段数据。此表中的示例行如下所示:
Department Date Status
------------------------------------
D1 2016/6/1 1
D1 2016/5/31 0
D1 2016/5/30 0
D1 2016/5/29 1
D1 2016/5/28 0
D1 2016/5/27 1
D2 2016/6/1 0
D2 2016/5/31 1
D2 2016/5/30 1
D2 2016/5/29 0
D2 2016/5/28 0
D2 2016/5/27 1
每个部门和每个日期都有一行。我想要的是,对于任何GIVEN DATE的每个部门,找到Status
在此日期之前为0的第一个日期。例如,对于2016/6/1的D1部门,结果是2015/5/30,对于D1,2016/5/31和5/30,它也是2015/5/30。对于D1,2016/5/29和5/28,它是2016/5/28。
我需要将结果输出为SELECT
结果并将其存储在另一个表中。因此,结果表与原始表具有完全相同的行数。结果表中可能包含三列:Department
,Date
,TargetDate
。
我对SQL / PL SQL没什么经验。我想我应该使用分析函数和窗口,但我真的无法提出查询。请给我一些建议。谢谢!
答案 0 :(得分:3)
with test_data (department, date_, status) as (
select 'D1', date '2016-06-01', 1 from dual union all
select 'D1', date '2016-05-31', 0 from dual union all
select 'D1', date '2016-05-30', 0 from dual union all
select 'D1', date '2016-05-29', 1 from dual union all
select 'D1', date '2016-05-28', 0 from dual union all
select 'D1', date '2016-05-27', 1 from dual union all
select 'D2', date '2016-06-01', 0 from dual union all
select 'D2', date '2016-05-31', 1 from dual union all
select 'D2', date '2016-05-30', 1 from dual union all
select 'D2', date '2016-05-29', 0 from dual union all
select 'D2', date '2016-05-28', 0 from dual union all
select 'D2', date '2016-05-27', 1 from dual
),
t (department, date_, status, lagged_status) as (
select department, date_, status,
lag(status) over (partition by department order by date_)
from test_data
)
select department, date_,
max(case when status = 0 and (lagged_status = 1 or lagged_status is null)
then date_ end)
over (partition by department order by date_
rows between unbounded preceding and current row) as target_date
from t
order by department, date_ desc
;
结果:
DEPARTMENT DATE_ TARGET_DATE
----------- ---------- -----------
D1 2016-06-01 2016-05-30
D1 2016-05-31 2016-05-30
D1 2016-05-30 2016-05-30
D1 2016-05-29 2016-05-28
D1 2016-05-28 2016-05-28
D1 2016-05-27 (null)
D2 2016-06-01 2016-06-01
D2 2016-05-31 2016-05-28
D2 2016-05-30 2016-05-28
D2 2016-05-29 2016-05-28
D2 2016-05-28 2016-05-28
D2 2016-05-27 (null)
12 rows selected.
请注意,“date”是Oracle关键字,不应用作列名;我使用了date_(我添加了一个下划线)。