Oracle-两列的差距和孤岛

时间:2019-02-01 12:46:04

标签: oracle

初始数据:

SELECT RCMOUVNT.MATRICULE, RCMOUVNT.DATENT, RCMOUVNT.DATOUT FROM RCMOUVNT
WHERE RCMOUVNT.MATRICULE = '81123404' order by DATENT asc;

MATRICULE   DATENT      DATOUT
81123404    04/09/17    30/11/17
81123404    01/12/17    31/07/18
81123404    01/02/19    31/01/20

使用SQL的预期结果:

MATRICULE   DATENT      DATOUT
81123404    04/09/17    31/07/18
81123404    01/02/19    31/01/20

我知道这是一个“差距与孤岛”问题,但我找不到任何答案。

1 个答案:

答案 0 :(得分:0)

使用这三个步骤的一种可能的解决方案

  • 找到的记录的不同分组(每断裂点得到分配一个新的GRP_ID)。请注意,在与DATAOUT匹配之前,您必须在上一行的DATENT中添加1天,以获取您的logik。另外,在第一行自动获得一个基团与NVL

  • 填写组的NULL(第二子查询) - 使用LAST_VALUE

  • 每个组的汇总(标准GROUP BY)-第三个查询分别使用GROUP BYMINMAX得到结果。

with q1   as (
select 
  MATRICULE,
  DATENT,
  DATOUT, 
  case when (nvl(lag(DATOUT +1) over (partition by MATRICULE order by DATENT),DATE'2500-01-01') <> DATENT) then 
     row_number() over (partition by MATRICULE order by DATENT) end grp
from RCMOUVNT 
), q2 as (
select 
  MATRICULE,
  DATENT,
  DATOUT,
  grp,
  last_value(grp ignore nulls) over (partition by MATRICULE order by DATENT) as grp2
from q1
)   
select 
    MATRICULE,  
    min(DATENT) DATENT, 
    max(DATOUT) DATOUT
from q2
group by MATRICULE, grp2
order by 1

 MATRICULE DATENT              DATOUT             
---------- ------------------- -------------------
  81123404 04.09.2017 00:00:00 31.07.2018 00:00:00
  81123404 01.02.2019 00:00:00 31.01.2020 00:00:00