我有以下数据:
ID Begin_Dt End_DT
101 201205 201208
101 201301 201309
101 201401 201502
101 201701 201801
现在,如果begin_DT是距上一个实例结束日期<= 9个月,则我需要覆盖end_dt或具有下一行的end_dt的上一行。我需要重复一遍,直到差异<= 9
让我们计算差异>>
Row_num ID Begin_Dt End_DT Diff
1 101 201205 201208 NA
2 101 201301 201309 5
3 101 201401 201502 4
4 101 201701 201801 23
第2行和第3行的差异为<= 9,因此解决方案应为
ID Begin_Dt End_DT Flag_corr
101 201205 201502 1
101 201301 201502 1
101 201401 201502 0
101 201701 201801 0
答案 0 :(得分:0)
尝试使用LAG功能。
with q0 as (
-- convert numbers to date and calculate lag
select to_date(begin_dt,'yyyymm') as begin_dt,
to_date(end_dt,'yyyymm') as end_dt,
lag(to_date(end_dt,'yyyymm'),1) over(order by begin_dt) as end_dt_prev
from dt
)
-- calculate difs and create flag
select q0.*,
months_between(end_dt,end_dt_prev) as diff,
case when months_between(end_dt,end_dt_prev) > 9 then 1 else 0 end as flag
from q0
答案 1 :(得分:0)
这是一种形式的空缺和岛屿问题,岛屿由9个月的空缺定义。开始的累积总和(基于滞后)定义了组;然后再执行一个步骤即可获得最大日期:
"Exception: Module loading registration_form failed: file
registration_form/security/ir.model.access.csv could not be processed:
No matching record found for external id 'model_registration_management'
in field 'Object' No matching record found for external id
'registration.group_management_user' in field 'Group'
Missing required value for the field 'Object' (model_id) - - -
Missing required value for the field 'Object' ("
答案 2 :(得分:0)
您说“我需要重复一遍,直到差异<= 9”。对我来说,这意味着您希望将行分组在一起,只要它们之间的总间隔不超过9个月即可。我不确定其他答案会尝试这样做。
您应该始终说出您所使用的Oracle数据库的版本。如果您使用的是12c或更高版本,则可以使用出色的MATCH_RECOGNIZE子句:
with data(ID,Begin_Dt,End_DT ) as (
select 101, to_date('201205', 'yyyymm'), to_date('201208', 'yyyymm') from dual union all
select 101, to_date('201301', 'yyyymm'), to_date('201309', 'yyyymm') from dual union all
select 101, to_date('201401', 'yyyymm'), to_date('201502', 'yyyymm') from dual union all
select 101, to_date('201701', 'yyyymm'), to_date('201801', 'yyyymm') from dual
)
select * from (
select d.*,
months_between(
begin_dt,
lag(end_dt,1,begin_dt) over(partition by id order by end_dt)
) mon
from data d
)
match_recognize(
partition by id order by begin_dt
measures final last(end_dt) new_end_dt
all rows per match
pattern(a b*)
define b as sum(mon) <= 9
);
ID BEGIN_DT NEW_END_DT END_DT MON
101 2012-05-01 00:00 2015-02-01 00:00 2012-08-01 00:00 0
101 2013-01-01 00:00 2015-02-01 00:00 2013-09-01 00:00 5
101 2014-01-01 00:00 2015-02-01 00:00 2015-02-01 00:00 4
101 2017-01-01 00:00 2018-01-01 00:00 2018-01-01 00:00 23