Sql server 2008 用于检测日期序列间隙的SQL Server逻辑

Sql server 2008 用于检测日期序列间隙的SQL Server逻辑,sql-server-2008,date,while-loop,sequence,common-table-expression,Sql Server 2008,Date,While Loop,Sequence,Common Table Expression,我有下表: Plan Start Date End Date Order ------------------------------------------ 1 1st Jan, 2014 31st Jan, 2014 1 1 1st Feb, 2014 24th Feb, 2014 2 1 25th Feb, 2014 30th Jun, 2014 3 1

我有下表:

     Plan     Start Date     End Date     Order    
    ------------------------------------------
      1    1st Jan, 2014  31st Jan, 2014   1
      1    1st Feb, 2014  24th Feb, 2014   2
      1   25th Feb, 2014  30th Jun, 2014   3
      1    7th Jul, 2014  28th Aug, 2014   4
      1    1st Sep, 2014  30th Sep, 2014   5
      1    1st Oct, 2014  31st Dec, 2014   6
从上述数据可以明显看出,对于计划1,订单1、2、3是连续的,然后我们有一个缺口,然后是订单4,然后是缺口,然后是订单5、6是连续的。对于计划1,我希望将覆盖范围捆绑如下:(1,2,3)、(4)、(5,6),预期结果集应如下所示:

     Plan     Start Date     End Date         
    -------------------------------------
      1    1st Jan, 2014  30th Jun, 2014 
      1    7th Jul, 2014  28th Aug, 2014 
      1    1st Sep, 2014  31st Dec, 2014

我使用了一个基本的while循环迭代逻辑来实现我想要的输出。然而,当有大量记录(比如100万条)时,while循环逻辑的性能会受到很大的影响(因为它是一个行操作)。我试图提出一种基于递归CTE的方法,但没有得到预期的结果。在这种情况下,任何可以使用批处理逻辑的输入都会非常有用。

中的子查询,其中
过滤掉连续的行。
选择中的子查询将查找日期范围结束

数据:

查询:

SELECT [Plan],D.StartDate, 
   [EndDate] = (SELECT MIN(E.EndDate)
                FROM #tab E
                WHERE E.EndDate >= D.EndDate
                 AND E.[Plan] = D.[Plan]
                 AND NOT EXISTS (SELECT 1
                                 FROM #tab E2
                                 WHERE DATEADD(d,1,E.StartDate) < E2.StartDate
                                   AND DATEADD(d,1,E.EndDate) >= E2.StartDate
                                   AND E.[Plan] = E2.[Plan]))
FROM #tab D
WHERE NOT EXISTS (SELECT 1
                  FROM #tab D2
                  WHERE D.StartDate <= DATEADD(d, 1,D2.EndDate)
                    AND D.EndDate > D2.EndDate
                    AND D.[Plan] = D2.[Plan])
ORDER BY [Plan], StartDate;
请参阅另一个查询

    declare @tab table ([Plan] INT, StartDate DATE, EndDate DATE, [Order] INT )      
    INSERT INTO @tab VALUES
    (1, '2014-01-01', '2014-01-31', 1),(1, '2014-02-01', '2014-02-24', 2),
    (1, '2014-02-25', '2014-06-30', 3),(1, '2014-07-07', '2014-08-28', 4),
    (1, '2014-09-01', '2014-09-30', 5),(1, '2014-10-01', '2014-12-31', 6)

    select [plan], Max(case when ro in (1,4,5) then startDate end) st,
    Max(case when ro in (3,4,0) then endDate end) et from (
    select *, ([order]-1) / 6 as grp,
    [order]%6 as ro, case when ([order] % 6)<4 and ([order] % 6)!=0 then 1
 when ([order] % 6)=4 then 2 else 3 end as subgrp
    from @tab) t group by [plan],grp,subgrp
declare@tab表([Plan]INT,StartDate日期,EndDate日期,[Order]INT)
插入到@tab值中
(1, '2014-01-01', '2014-01-31', 1),(1, '2014-02-01', '2014-02-24', 2),
(1, '2014-02-25', '2014-06-30', 3),(1, '2014-07-07', '2014-08-28', 4),
(1, '2014-09-01', '2014-09-30', 5),(1, '2014-10-01', '2014-12-31', 6)
选择[计划],最大值(ro在(1,4,5)时的情况,然后选择开始日期结束)st,
最大值(ro输入(3,4,0)然后结束日期结束时的情况)et自(
选择*,([订单]-1)/6作为grp,
[订单]%6作为ro,情况为([订单]%6)
╔══════╦═════════════════════╦═════════════════════╗
║ Plan ║      StartDate      ║       EndDate       ║
╠══════╬═════════════════════╬═════════════════════╣
║    1 ║ 2014-01-01 00:00:00 ║ 2014-06-30 00:00:00 ║
║    1 ║ 2014-07-07 00:00:00 ║ 2014-08-28 00:00:00 ║
║    1 ║ 2014-09-01 00:00:00 ║ 2014-12-31 00:00:00 ║
╚══════╩═════════════════════╩═════════════════════╝
    declare @tab table ([Plan] INT, StartDate DATE, EndDate DATE, [Order] INT )      
    INSERT INTO @tab VALUES
    (1, '2014-01-01', '2014-01-31', 1),(1, '2014-02-01', '2014-02-24', 2),
    (1, '2014-02-25', '2014-06-30', 3),(1, '2014-07-07', '2014-08-28', 4),
    (1, '2014-09-01', '2014-09-30', 5),(1, '2014-10-01', '2014-12-31', 6)

    select [plan], Max(case when ro in (1,4,5) then startDate end) st,
    Max(case when ro in (3,4,0) then endDate end) et from (
    select *, ([order]-1) / 6 as grp,
    [order]%6 as ro, case when ([order] % 6)<4 and ([order] % 6)!=0 then 1
 when ([order] % 6)=4 then 2 else 3 end as subgrp
    from @tab) t group by [plan],grp,subgrp