oracle sql根据模式需要有关数据的帮助

时间:2018-12-15 01:09:23

标签: sql oracle

我在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

我想要下面的Out

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

让我解释一下模式以及输出结果如何

第二行set_off_dtset_term_dt +1的结果

第三行set_off_dt是第二行set_term_dt +1的结果

第四行set_eff_dt不是第三行set_term_dt+1的结果,因此这里可能是分组休息b

第五行set_eff_dt还是第四行set_term_dt+1的结果 因此它将被折叠到第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在新行中,我只是能够识别该标志...但是我仍然不明白如何代表该数据解决崩溃问题。

2 个答案:

答案 0 :(得分:2)

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

  1. 确定组开始的位置。为此,我对前面的set_trm_dtcase逻辑进行了滞后处理,以查看是否没有“连接”。
  2. 对标志进行累加,以为每行分配一个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;

答案 1 :(得分:1)

请考虑对所生成的列进行累加以产生一个分组变量,该分组变量需要两个CTE:一个用于您的 flg 计算,另一个用于使用窗口函数的 flg 累积和。 。最后,通过 cum_flg 进行聚合(但有条件地将第一个分组值从1开始添加1)。

WITH sub AS
  (SELECT SET_NO, SET_EFF_DT, SET_TRM_DT,
          CASE WHEN LEAD (SET_EFF_DT,1) OVER (ORDER BY SET_EFF_DT)-1 = SET_TRM_DT
               THEN 1 
               ELSE 0 
          END AS flg
   FROM xx_fl_test),

   calc AS
   (SELECT SET_NO, SET_EFF_DT, SET_TRM_DT,
           SUM (flg) OVER (PARTITION BY SET_NO ORDER BY SET_EFF_DT)  AS cum_flg
    FROM sub)

SELECT SET_NO, 
       MIN(SET_EFF_DT) AS MIN_SET_EFF_DT,
       MAX(SET_TRM_DT) AS MAX_SET_TRM_DT
FROM calc
GROUP BY SET_NO,
         CASE cum_flg
              WHEN 1
              THEN cum_flg + 1
         END

Rextester Demo