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.
注意してください、「日」はOracleのキーワードで、列名として使用すべきではありません。代わりにdate_を使用しました(私はアンダースコアを追加しました)。
分析機能は正しいですが(ウィンドウ処理)、最初に要件を明確にしてください。 D2と2016/5/27の望ましい結果は何ですか?つまり、ある部門の最も古い行がステータス1(またはより一般的には、ゼロとは異なる)を持つ場合はどうなりますか? ....と実際に待って、ステータスが0であるが、あなたの例では、D1と5/29と5/28の日付では、結果は5/27でなければならないと言っていますが、5/27はステータス1 。 どうか明らかにしてください。 (できれば、あなたの投稿をコメントで編集することによって)。 – mathguy
@mathguyコメントありがとうございました。 1)最も古い行がステータス1を持つか、またはゼロとは異なる場合、 'TargetDate'はヌルでなければなりません。その日付の前にステータス0の日付が見つからないことを意味します。 D1と5/29、5/28については、結果は2016/5/28でなければなりません。それはタイプミスでした。私はすでに元の投稿でそれを修正しました。 – tete
クール、ありがとう。私が要件を理解していることを確認するためのもう1つの質問。毎日のように、ステータスがゼロの最新の日付(ステータスがゼロの場合は日付自体、または最初のゼロが見つかるまでは履歴に戻っている可能性があります)に移動します。次に、ステータスゼロの最新の日付を選択しないでください。むしろ、ステータスゼロの連続した日のシーケンスの一部である場合は、その連続シーケンスから最も古い日付を選択します。そのため、6/1、5/31、5/30の回答はD1の5/30です。右?そうであれば、これはいわゆる「タブビトサン」法の応用である。 – mathguy