首页 > 解决方案 > oracle sql根据模式需要数据帮助

问题描述

我在 oracle 数据库中有示例数据,如下所示:

set_no  set_eff_dt    set_term_dt
1000    1/1/2015    12/31/2016
1000    1/1/2017    10/31/2017
1000    11/1/2017   12/31/2018
1000    2/1/2019    10/31/2019
1000    11/1/2019   10/31/2020

我想要像下面这样的输出

1000    1/1/2015    12/31/2018
1000    2/1/2019    10/31/2020

让我解释一下模式以及输出将如何出现

第二行set_off_dt是结果 set_term_dt +1

第三行set_off_dtset_term_dt +1第二行的结果

第 4 行set_eff_dt不是set_term_dt+1第三行的结果,所以这里是分组休息可能 b

第 5 行set_eff_dt再次是set_term_dt+1第 4 行的结果,因此它将与第 4 行一起折叠,如输出所示

在同样的模式中,我们有数千条记录,我们希望按照描述的逻辑折叠

what i have tried

SELECT SET_NO,SET_EFF_DT,
 case when LEAD (SET_EFF_DT,1) OVER (ORDER BY SET_EFF_DT)-1 = set_trm_dt then 1 else 0 end flg
 FROM xx_fl_test

SET_EFF_DT如果=在新行中,我只能识别标志set_trm_dt......但我仍然不明白如何代表这些数据处理折叠的问题。

标签: sqloracle

解决方案


这是一个差距和孤岛问题。我将通过以下步骤计算分组变量来解决:

  1. 确定一个小组从哪里开始。为此,我在前面set_trm_dtcase逻辑上做了一个滞后,看看是否没有“连接”。
  2. 对标志进行累积总和,以将 a 分配grp给每一行。
  3. 按 聚合grp

代码如下所示:

select set_no, min(set_eff_dt), max(set_trm_dt)
from (select t.*,
             sum(case when set_eff_dt > prev_set_trm_dt + 1 then 1 else 0 end) over (partition by set_no order by set_eff_dt) as grp
      from (select t.*,
                   lag(set_trm_dt) over (partition by set_no order by set_eff_dt) as prev_set_trm_dt
            from xx_fl_test t
           ) t
     ) t
group by set_no, grp;

推荐阅读