Oracle 查询以查找给定数据集中新更改之前的最小更改
Oracle query to find the least change before a new change in a given data set
我正在尝试使用它自己的数据对 table 进行更新,但我正在努力针对我的要求提出查询
请看下面的数据
KEY VALID_DATE STATUS INACTIVE_DT
1 7/2/2019 ACTIVE
1 7/27/2018 INACTIVE
1 8/19/2018 INACTIVE
1 9/7/2018 ACTIVE
1 1/15/2019 INACTIVE
1 1/21/2019 INACTIVE
2 3/31/2019 INACTIVE
2 4/1/2019 INACTIVE
3 7/2/2019 ACTIVE
3 7/3/2019 INACTIVE
3 7/4/2019 INACTIVE
3 7/5/2019 ACTIVE
3 7/6/2019 INACTIVE
我需要使用以下条件更新同一个 table 上的 inactive_dt 字段。
1) DATA 需要被KEY 列partitioned/grouped。
2) 每当状态变为不活动时使用 valid_date 字段填充 inactive_dt
3) 对于连续的非活动日期,保留第一个非活动日期。
4) 如果在两个非活动日期之间有一个活动 dt,那么第二个非活动日期应该获得最新值而不是第一个值
查看下面的输出
KEY VALID_DATE STATUS INACTIVE_DT
1 7/2/2019 ACTIVE NULL
1 7/27/2018 INACTIVE 7/27/2018
1 8/19/2018 INACTIVE 7/27/2018
1 9/7/2018 ACTIVE NULL
1 1/15/2019 INACTIVE 1/15/2019
1 1/21/2019 INACTIVE 1/15/2019
2 3/31/2019 INACTIVE 3/31/2019
2 4/1/2019 INACTIVE 3/31/2019
2 6/1/2019 ACTIVE NULL
3 7/2/2019 ACTIVE NULL
3 7/3/2019 INACTIVE 7/3/2019
3 7/4/2019 INACTIVE 7/3/2019
3 7/5/2019 ACTIVE NULL
3 7/6/2019 INACTIVE 7/6/2019
能否请您给我一些实现此目标的最佳方法的建议。
感谢您的帮助
您可以在状态更改时对行求和,这使您可以将此列用作附加分区键:
select key, valid_date, status, grp,
case
when status = 'ACTIVE' then null
else first_value(valid_date) over (partition by key, grp, status)
end dt
from (select t.*, sum(case status when 'ACTIVE' then 1 end)
over (partition by key order by valid_date) grp from t)
order by key, valid_date
我正在尝试使用它自己的数据对 table 进行更新,但我正在努力针对我的要求提出查询
请看下面的数据
KEY VALID_DATE STATUS INACTIVE_DT
1 7/2/2019 ACTIVE
1 7/27/2018 INACTIVE
1 8/19/2018 INACTIVE
1 9/7/2018 ACTIVE
1 1/15/2019 INACTIVE
1 1/21/2019 INACTIVE
2 3/31/2019 INACTIVE
2 4/1/2019 INACTIVE
3 7/2/2019 ACTIVE
3 7/3/2019 INACTIVE
3 7/4/2019 INACTIVE
3 7/5/2019 ACTIVE
3 7/6/2019 INACTIVE
我需要使用以下条件更新同一个 table 上的 inactive_dt 字段。
1) DATA 需要被KEY 列partitioned/grouped。
2) 每当状态变为不活动时使用 valid_date 字段填充 inactive_dt
3) 对于连续的非活动日期,保留第一个非活动日期。
4) 如果在两个非活动日期之间有一个活动 dt,那么第二个非活动日期应该获得最新值而不是第一个值
查看下面的输出
KEY VALID_DATE STATUS INACTIVE_DT
1 7/2/2019 ACTIVE NULL
1 7/27/2018 INACTIVE 7/27/2018
1 8/19/2018 INACTIVE 7/27/2018
1 9/7/2018 ACTIVE NULL
1 1/15/2019 INACTIVE 1/15/2019
1 1/21/2019 INACTIVE 1/15/2019
2 3/31/2019 INACTIVE 3/31/2019
2 4/1/2019 INACTIVE 3/31/2019
2 6/1/2019 ACTIVE NULL
3 7/2/2019 ACTIVE NULL
3 7/3/2019 INACTIVE 7/3/2019
3 7/4/2019 INACTIVE 7/3/2019
3 7/5/2019 ACTIVE NULL
3 7/6/2019 INACTIVE 7/6/2019
能否请您给我一些实现此目标的最佳方法的建议。
感谢您的帮助
您可以在状态更改时对行求和,这使您可以将此列用作附加分区键:
select key, valid_date, status, grp,
case
when status = 'ACTIVE' then null
else first_value(valid_date) over (partition by key, grp, status)
end dt
from (select t.*, sum(case status when 'ACTIVE' then 1 end)
over (partition by key order by valid_date) grp from t)
order by key, valid_date