2017-05-23 197 views
0

我被困在一些看起来在DB2简单,这是我的表SQL连续日期范围

ID | BEG_DT     | END_DT    
---- ------------------------- ------------------------- 

1 | 2016-09-01 00:00:00.0 | 2016-09-30 00:00:00.0  
2 | 2016-10-01 00:00:00.0 | 2016-10-31 00:00:00.0   
3 | 2016-12-01 00:00:00.0 | 2016-12-31 00:00:00.0  
4 | 2017-01-01 00:00:00.0 | 2017-01-31 00:00:00.0  
5 | 2017-02-01 00:00:00.0 | 2017-02-28 00:00:00.0  
6 | 2017-04-01 00:00:00.0 | 2017-04-30 00:00:00.0  
7 | 2017-05-01 00:00:00.0 | 2017-05-31 00:00:00.0  
8 | 2017-06-01 00:00:00.0 | 2017-06-30 00:00:00.0  
9 | 2017-07-01 00:00:00.0 | null 

我想返回开始日期和结束日期,例如连续周期的查询,在这种情况下,查询需要返回:

BEG_DT     |END_DT    
------------------------- |------------------------- 
2016-09-01 00:00:00.0  |2016-10-31 00:00:00.0  
2016-12-01 00:00:00.0  |2017-02-28 00:00:00.0  
2017-04-01 00:00:00.0  |null 
+6

SQL Server或DB2? – GurV

+2

这是“缺口和岛屿”问题。如果你知道它叫什么,搜索起来会更容易。 :) – Donnie

+0

在这里可以找到很棒的(免费的)SQL Cookbook中的“查找时间序列中的差距”一章,也就是http://www.ids-system.de/db2-luw-fuer-die- eigene-ausbildung#sql – MichaelTiefenbacher

回答

0

嗨,你可以使用递归找到所有的连续周期,然后用天功能以消除所有的更大一部分时间。例如2017-05-01至2017-06-30是2017-04-01的一部分为空。

WITH temp1 (
id 
,beg_dt 
,end_dt 
) 
AS (
SELECT m.* 
FROM WORK.MYTABLE m 
) 
,temp2 (
id 
,beg_dt 
,end_dt 
) 
    AS (
    SELECT 1 
    ,beg_dt 
    ,end_dt 
FROM temp1 

UNION ALL 

SELECT 2 
    ,tt1.beg_dt 
    ,tt2.end_dt 
FROM temp1 tt1 
    ,temp2 tt2 
WHERE tt1.end_dt = tt2.beg_Dt - 1 day 
) 
    SELECT id 
    ,beg_dt 
    ,end_dt 
    FROM temp2 a 
    WHERE NOT EXISTS (
    SELECT 1 
    FROM temp2 b 
    WHERE a.beg_dt BETWEEN b.beg_Dt 
      AND coalesce(b.end_dt, '9999-12-31') 
     AND days(coalesce(b.end_dt, '9999-12-31')) - days(b.beg_dt) > days(coalesce(a.end_dt, '9999-12-31')) - days(a.beg_dt) 
    )