SQL Date Range Split

前端 未结 2 1710
小鲜肉
小鲜肉 2021-02-04 17:26

Can you please let me know the SQL to split date ranges when they overlap?

Data (sample data with a date range and possibly other columns):

    Col1 From         


        
相关标签:
2条回答
  • 2021-02-04 17:54

    Skliwz's answer adapted for SQL Server:

    DECLARE @DateTest TABLE 
    (
        FromDate datetime,
        ToDate datetime 
    )
    
    insert into @DateTest (FromDate, ToDate)
    (
    select cast('1/1/2008' as datetime), cast('12/31/2010' as datetime)
    union
    select cast('1/1/2009' as datetime), cast('12/31/2012' as datetime)
    union
    select cast('1/1/2009' as datetime), cast('12/31/2014' as datetime)
    )
    
    SELECT 
      FromDate , min(ToDate)
    FROM (
      SELECT t1.FromDate, t2.ToDate
      FROM 
        @DateTest t1, 
        @DateTest t2
      WHERE t1.FromDate < t2.ToDate
    
      UNION
    
      SELECT dateadd(DAY, 1, t1.ToDate), t2.ToDate
      FROM 
        @DateTest t1, 
        @DateTest t2
      WHERE dateadd(DAY, 1, t1.ToDate) < t2.ToDate
    ) allRanges
    group by FromDate
    
    0 讨论(0)
  • 2021-02-04 18:07

    This should do the trick (MySQL dialect, but easily adaptable)

    Initial setup

    SQL query: SELECT * FROM `test` LIMIT 0, 30 ;
    Rows: 3
    start       end
    2008-01-01  2010-12-31
    2009-01-01  2012-12-31
    2009-01-01  2014-12-31
    

    Query

    SELECT 
      `start` , min( `end` )
    FROM (
      SELECT t1.start, t2.end
      FROM test t1, test t2
      WHERE t1.start < t2.end
      UNION
      SELECT t1.end + INTERVAL 1 DAY , t2.end
      FROM test t1, test t2
      WHERE t1.end + INTERVAL 1 DAY < t2.end
      UNION
      SELECT t1.start, t2.start - INTERVAL 1 DAY
      FROM test t1, test t2
      WHERE t1.start < t2.start - INTERVAL 1 DAY
    ) allRanges
    GROUP BY `start`
    

    Result

    start       min( `end` )
    2008-01-01  2008-12-31
    2009-01-01  2010-12-31
    2011-01-01  2012-12-31
    2013-01-01  2014-12-31
    
    0 讨论(0)
提交回复
热议问题