Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于查找ID的开始和结束日期的SQL_Sql_Oracle_Gaps And Islands - Fatal编程技术网

用于查找ID的开始和结束日期的SQL

用于查找ID的开始和结束日期的SQL,sql,oracle,gaps-and-islands,Sql,Oracle,Gaps And Islands,我有一个带有ID、开始日期和结束日期列的表 表: ID start_date end_date 1 01/01/2017 01/01/2018 1 01/01/2018 01/01/2019 1 01/01/2019 01/01/2020 2 01/01/2016 01/01/2017 2 01/01/2017 01/01/2018 2 01/01/2019 01/01/2020 我想编写一个查询以

我有一个带有ID、开始日期和结束日期列的表

表:

ID    start_date    end_date
1     01/01/2017    01/01/2018
1     01/01/2018    01/01/2019
1     01/01/2019    01/01/2020
2     01/01/2016    01/01/2017
2     01/01/2017    01/01/2018
2     01/01/2019    01/01/2020
我想编写一个查询以获得以下输出:

输出:

ID    start_date    end_date
1     01/01/2017    01/01/2020
2     01/01/2016    01/01/2018
2     01/01/2019    01/01/2020

这是一种缺口和孤岛的形式

在这种情况下,我的建议是使用累计最大值来查看是否与前面的行有任何重叠,并使用该值来确定“孤岛”从何处开始。然后,使用累积和定义孤岛和聚合:

select id, min(start_date), max(end_date
from (select t.*,
             sum(case when prev_end_date >= start_date then 0 else 1 end) over (partition by id order by start_date) as grp
      from (select t.*,
                   lag(end_date) over (partition by id
                                       order by start_date
                                       rows between unbounded preceding and 1 preceding
                                      ) as prev_end_date
            from t
           ) t
      ) t
group by id, grp;

您可以进行累积求和以解决此差异和孤岛问题:

select 
    id,
    min(start_date) start_date,
    max(end_date) end_date
from (
    select 
        t.*,
        sum(case when start_date = lag_end_date then 0 else 1 end) 
            over(partition by id order by start_date) grp
    from (
        select 
            t.*,
            lag(end_date) over(partition by id order by start_date) lag_end_date
        from mytable t
    ) t
) t
group by id, grp
order by id, grp

ID | START_DATE | END_DATE -: | :--------- | :--------- 1 | 01/01/2017 | 01/01/2020 2 | 01/01/2016 | 01/01/2018 2 | 01/01/2019 | 01/01/2020 ID |开始日期|结束日期 -: | :--------- | :--------- 1 | 01/01/2017 | 01/01/2020 2 | 01/01/2016 | 01/01/2018 2 | 01/01/2019 | 01/01/2020
@普拉桑纳库玛。这是在GMB推出类似解决方案的四分钟前发布的。你能解释一下你为什么喜欢那个解决方案吗?
     Select id, Min(startdate), Max(case 
          when 
           lag(enddate) 
         over
    (partition by id order by id) =startdate
       then 
       Enddate end) from table group by
       id;