我有下表:
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的方法,但无法得到理想的结果。在这种情况下,任何可以使用批处理逻辑的输入都非常有用。
答案 0 :(得分:0)
WHERE
中的子查询过滤掉连续的行。 SELECT
中的子查询将找到日期范围结束。
数据:
CREATE TABLE #tab([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],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;
的 LiveDemo
强>
输出:
╔══════╦═════════════════════╦═════════════════════╗
║ 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 ║
╚══════╩═════════════════════╩═════════════════════╝
答案 1 :(得分:0)
查看其他查询
;(function(){
var app = angular.module('myawesomeapp',[])
.directive('restrictInput', [function(){
return {
restrict: 'A',
link: function (scope, element, attrs) {
var ele = element[0];
var regex = RegExp(attrs.restrictInput);
var value = ele.value;
ele.addEventListener('keyup',function(e){
if (regex.test(ele.value)){
value = ele.value;
}else{
ele.value = value;
}
});
}
};
}]);
}());