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