【问题标题】:SQL Date Range SplitSQL 日期范围拆分
【发布时间】:2008-10-08 22:07:54
【问题描述】:

能否告诉我在日期范围重叠时拆分日期范围的 SQL?

数据(具有日期范围和可能的其他列的示例数据):

    Col1 FromDate ToDate
 1. 1    1/1/2008 31/12/2010
 2. 1    1/1/2009 31/12/2012
 3. 1    1/1/2009 31/12/2014

输出:

   Col1  From Date ToDate
1. 1     1/1/2008 31/12/2008 (from row 1 above)
2. 1     1/1/2009 31/12/2010 (from rows 1,2 and 3 above)
3. 1     1/1/2011 31/12/2012 (from rows 2 and 3 above)
4. 1     1/1/2013 31/12/2014 (from row 3 above)

【问题讨论】:

  • 好的,我没有完整的答案,但这里有几点需要考虑。 1. 第一个时间块是从表组中选择 min(FromDate) by FromDateprint("code sample"); 2. 然后第一个块的结束是从表组中选择 min(FromDate) by FromDate where FromDate > "start of block" 3.根据需要重复。 :)

标签: sql date-range


【解决方案1】:

这应该可以解决问题(MySQL 方言,但很容易适应)

初始设置

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

查询

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`

结果

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

【讨论】:

    【解决方案2】:

    Skliwz 的答案适用于 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 2013-11-09
      • 2016-08-15
      • 2010-09-13
      • 1970-01-01
      相关资源
      最近更新 更多