Joining together consecutive date validity intervals

后端 未结 4 2012
予麋鹿
予麋鹿 2021-01-14 02:59

I have a series of records containing some information (product type) with temporal validity.

I would like to meld together adjacent validity intervals, provided tha

4条回答
  •  再見小時候
    2021-01-14 03:08

    It seems like there should be an easier way, but a combination of an analytical query (to find the different gaps) and a hierarchical query (to connect the rows that are continuous) works:

    with data as (
        select 'A' product, to_date('7/1/2013', 'MM/DD/YYYY') start_date, to_date('7/31/2013', 'MM/DD/YYYY') end_date from dual union all
        select 'A' product, to_date('8/1/2013', 'MM/DD/YYYY') start_date, to_date('8/31/2013', 'MM/DD/YYYY') end_date from dual union all
        select 'A' product, to_date('9/1/2013', 'MM/DD/YYYY') start_date, to_date('9/30/2013', 'MM/DD/YYYY') end_date from dual union all
        select 'B' product, to_date('10/1/2013', 'MM/DD/YYYY') start_date, to_date('10/31/2013', 'MM/DD/YYYY') end_date from dual union all
        select 'B' product, to_date('11/1/2013', 'MM/DD/YYYY') start_date, to_date('11/30/2013', 'MM/DD/YYYY') end_date from dual union all
        select 'A' product, to_date('12/1/2013', 'MM/DD/YYYY') start_date, to_date('12/31/2013', 'MM/DD/YYYY') end_date from dual union all
        select 'A' product, to_date('1/1/2014', 'MM/DD/YYYY') start_date, to_date('1/31/2014', 'MM/DD/YYYY') end_date from dual union all
        select 'A' product, to_date('2/1/2014', 'MM/DD/YYYY') start_date, to_date('2/28/2014', 'MM/DD/YYYY') end_date from dual union all
        select 'A' product, to_date('3/1/2014', 'MM/DD/YYYY') start_date, to_date('3/31/2014', 'MM/DD/YYYY') end_date from dual
    ),
    start_points as
    (
        select product, start_date, end_date, prior_end+1, case when prior_end + 1 = start_date then null else 'Y' end start_point 
        from (
            select product, start_date, end_date, lag(end_date,1) over (partition by product order by end_date) prior_end
            from data
        )
    )
    select product, min(start_date) start_date, max(end_date) end_date
    from (
        select product, start_date, end_date, level, connect_by_root(start_date) root_start
        from start_points
        start with start_point = 'Y'
        connect by prior end_date = start_date - 1
        and prior product = product
    )
    group by product, root_start;
    
    
    
    PRODUCT START_DATE END_DATE 
    ------- ---------- ---------
    A       01-JUL-13  30-SEP-13
    A       01-DEC-13  31-MAR-14
    B       01-OCT-13  30-NOV-13
    

提交回复
热议问题