将多行 phone 数据合并为显示开始和结束日期的单行的脚本

Script that consolidates multiple rows of phone data into single rows showing start and end dates

以下table,我愿意:

我。合并行,以便对于每个 phone 类型,相同 phone 数字的集合合并为具有单一开始和结束日期

的唯一 phone 数字

二。综合 phone 号码的开始日期是集合的最早开始日期 合并的 phone 号码的结束日期是集合的最新结束日期

三。此外,我想确保当某些不同的 phone 数字按时间顺序夹在一组相同的 phone 数字中时(由红色破折号箭头表示),那些 phone 相同的数字没有合并成一行。相反,它们被合并为单独的集合。这是因为按时间顺序,它们现在是分开的集合

我目前使用的脚本满足第一和第二个要求,但不满足第三个要求

SELECT CLAIMANT_ID, PHONE_TYPE, PHONE_NUMBER, 
Min(START_DATE), Max(END_DATE) KEEP (DENSE_RANK FIRST ORDER BY END_DATE DESC NULLS FIRST)
FROM ClaimantData
GROUP BY CLAIMANT_ID, PHONE_TYPE, PHONE_NUMBER

有谁知道是否有任何方法可以增强脚本(或有一个完全不同的脚本)来满足第三个要求?

期望的结果如下:

用于插入的示例数据

CREATE TABLE CLAIMANTDATA (    
CLAIMANT_ID NUMBER(9) NOT NULL,
PHONE_TYPE VARCHAR2(50 BYTE) NOT NULL,
PHONE_NUMBER VARCHAR2(50 BYTE) NULL,
START_DATE DATE NOT NULL,
END_DATE DATE NULL
);

Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Primary',7653030303,to_date('12-JAN-12','DD-MON-RR'),to_date('23-JAN-12','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Primary',7653030303,to_date('09-JAN-12','DD-MON-RR'),to_date('12-JAN-12','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Primary',7653030303,to_date('01-JAN-12','DD-MON-RR'),to_date('09-JAN-12','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('09-MAR-11','DD-MON-RR'),to_date('01-JAN-12','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('22-FEB-11','DD-MON-RR'),to_date('09-MAR-11','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('19-AUG-10','DD-MON-RR'),to_date('22-FEB-11','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('16-AUG-10','DD-MON-RR'),to_date('19-AUG-10','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',2062009876,to_date('14-AUG-10','DD-MON-RR'),to_date('16-AUG-10','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('08-APR-10','DD-MON-RR'),to_date('14-AUG-10','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('06-APR-10','DD-MON-RR'),to_date('08-APR-10','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('08-JUL-09','DD-MON-RR'),to_date('06-APR-10','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('15-JAN-09','DD-MON-RR'),to_date('08-JUL-09','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7650880880,to_date('22-DEC-08','DD-MON-RR'),to_date('15-JAN-09','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('07-AUG-08','DD-MON-RR'),to_date('22-DEC-08','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('06-AUG-08','DD-MON-RR'),to_date('07-AUG-08','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('06-AUG-08','DD-MON-RR'),to_date('06-AUG-08','DD-MON-RR'));
Insert into CLAIMANTDATA (CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,START_DATE,END_DATE) values (504,'Alternate',7651000001,to_date('13-NOV-07','DD-MON-RR'),to_date('28-MAR-08','DD-MON-RR'));

这就是孤岛和缺口问题。

您可以使用解析函数如下:

Select CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER,
        Min(start_date),
        Max(end_date)
  From
(Select t.*,
       Row_number() over (partition by CLAIMANT_ID, PHONE_TYPE order by start_date) as rn,
       Row_number() over (partition by CLAIMANT_ID, PHONE_TYPE, PHONE_NUMBER order by start_date) as rn_p
   From CLAIMANTDATA t) t
Group by CLAIMANT_ID,PHONE_TYPE,PHONE_NUMBER, rn-rn_p

在 Oracle 12.1 或更高版本中,解决此类间隙和孤岛问题的最简单方法是使用 match_recognize 子句。

select claimant_id, phone_type, phone_number, start_date, end_date
from   claimantdata
match_recognize (
  partition by claimant_id, phone_type
  order     by start_date
  measures  a.phone_number as phone_number,
            a.start_date as start_date, last(end_date) as end_date
  pattern   ( a b* )
  define    b as phone_number = a.phone_number and start_date = prev(end_date)
);