合并两个表并找到重叠的日期和差距

Merge two tables and find overlapping dates and Gaps

我想使用 oracle 分析函数解决以下 ID 100 和 101 作为给定输出的场景。有什么想法吗?

TABLE答:

ID   ValidFrom   ValidTo
100  1/1/2009    12/31/2010
100  1/1/2011    3/31/2012
101  8/1/2013    7/31/2014
101  8/1/2014    8/31/2014

TABLE B

ID   ValidFrom   ValidTo
100  11/1/2008   12/31/2011
100  2/1/2012    2/29/2012
101  8/1/2013    6/30/2014
101  7/1/2014    8/31/2014

输出:

ID   ValidFrom   ValidTo
100  11/1/2008  12/31/2008
100  1/1/2009   12/31/2010
100  1/1/2011   12/31/2011
100  1/1/2012   1/31/2012
100  2/1/2012   2/29/2012
100  3/1/2012   3/31/2012
---------------------------
101  8/1/2013   6/30/2014
101  7/1/2014   7/31/2014
101  8/1/2014   8/31/2014

此查询使用解析 lead() 完成工作。列 note 显示行是否来自您的数据或是否缺少间隙:

select id, d1, d2, case dir when 3 then 'GAP' end note 
  from (
    select id, 
           case when dir = 2 
                 and lead(dir) over (partition by id order by dt) = 1
                 and lead(dt) over (partition by id order by dt) <> dt + 1
                then dt + 1 
                else dt
           end d1,
           case when dir = 2 
                 and lead(dir) over (partition by id order by dt) = 1
                 and lead(dt) over (partition by id order by dt) <> dt + 1
                then 3 
                else dir
           end dir,
           case when lead(dir) over (partition by id order by dt) = 1 
                then lead(dt)  over (partition by id order by dt) - 1
                else lead(dt)  over (partition by id order by dt) 
            end d2
      from (
        select * from a unpivot (dt for dir in (validfrom as 1, validto as 2)) union 
        select * from b unpivot (dt for dir in (validfrom as 1, validto as 2)) ) )
  where dir in (1, 3)

dbfiddle demo

起初数据是反透视的,只是将所有日期都放在一列中,这样更容易进行进一步分析。联合删除重复值。 dir 列告知这是 from 还是 to 日期。然后根据此方向的类型应用 lead 逻辑。我认为它可以稍微简化 :)