【问题标题】:SQL Server - Gaps and IslandsSQL Server - 差距和孤岛
【发布时间】:2020-06-25 09:06:07
【问题描述】:

我有一张包含开始日期和结束日期的表格, 例如,

地点 ID |开始日期 |结束日期

1 | 2020-01-01 | 2020-01-04
2 | 2020-01-03 | 2020-01-06
1 | 2020-01-10 | 2020-01-15
2 | 2020-01-20 | 2020-01-23

我需要编写一个脚本来获取每个 PlaceID 的表中没有的日期范围。(现在考虑一月)
对于 PlaceID 1 - 我需要输出日期范围为 - 2020-01-05 到 2020-01-09 和 2020-01-16 到 2020-01-31
对于 PlaceID 2 - 我需要输出日期范围为 - 2020-01-01 到 2020-01-02、2020-01-07 到 2020-01-19 和 2020-01-24 至 2020-01-31

我可以使用的这背后的sql逻辑是什么?

【问题讨论】:

    标签: sql-server date


    【解决方案1】:

    以下是给出其中一个 PlaceID 的结果的脚本,如果我想获取两个/所有可用 placeID 的值该怎么办

    DECLARE @t table(PlaceID int, StartDate date, EndDate date);
    INSERT @t(PlaceID, StartDate, EndDate) VALUES
    (1,'20200101','20200104'),(1,'20200110','20200115'),
    (2,'20200103','20200106'),(2,'20200120','20200123');
    
    
    -- input parameters 
    DECLARE @PlaceIDofInterest   int  = 1,
           @StartDateOfInterest date = '20200101', 
           @EndDateOfInterest   date = '20200131';
       
    ;WITH date_range(d) AS -- the entire range of days we care about
    (
     SELECT @StartDateOfInterest UNION ALL
     SELECT DATEADD(DAY, 1, d) FROM date_range
            WHERE d < @EndDateOfInterest
    ),
    islands AS -- grouped sets of days _not_ covered
    (
     SELECT r.d, island = DATEADD(DAY, DENSE_RANK() OVER (ORDER BY r.d) * -1, r.d) ,@PlaceIDofInterest as PlaceID
       FROM date_range AS r
       LEFT OUTER JOIN @t AS t
         ON  r.d >= t.StartDate 
         AND r.d <= t.EndDate
         AND t.PlaceID = @PlaceIDofInterest
       WHERE t.PlaceID IS NULL
    )
    
    SELECT MIN(d), MAX(d),PlaceID -- for each island, grab the start and end
     FROM islands 
     GROUP BY island ,PlaceID
     ORDER BY MIN(d);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多