在此基础上增加一个限制条件,即在任意两个日期之间只能有一个排除范围。
CREATE TABLE worktable (
_Id INT
, _Start DATETIME
, _End DATETIME
);
INSERT INTO worktable VALUES
(1, '2015-11-09 00:00:00', '2015-11-09 00:45:00')
, (2, '2015-11-09 00:00:00', '2015-11-11 21:45:00')
, (3, '2015-11-09 00:00:00', '2015-11-10 21:00:00')
, (4, '2015-11-10 10:00:00', '2015-11-11 10:00:00')
, (5, '2015-11-10 10:00:00', '2015-11-11 21:45:00')
With getDates As (
SELECT _Id
, a = _Start
, b = _End
, c = DATEADD(hh, 9
, DATEADD(DAY,DATEDIFF(DAY, 0, _Start) / 7 * 7
+ 7 * Cast(Sign(1 - DatePart(dw, _Start)) + 1 as bit), 1))
, d = DATEADD(hh, 18
, DATEADD(DAY,DATEDIFF(DAY, 0, _Start) / 7 * 7
+ 7 * Cast(Sign(1 - DatePart(dw, _Start)) + 1 as bit), 2))
FROM worktable
), getDiff As (
SELECT c_a = DATEDIFF(mi, a, c)
, c_b = DATEDIFF(mi, b, c)
, b_d = DATEDIFF(mi, d, b)
, a, b, c, d, _id
FROM getDates
)
Select _id
, (c_a + ABS(c_a)) / 2
- (c_b + ABS(c_b)) / 2
+ (b_d + ABS(b_d)) / 2
FROM getDiff;
c
是起始日期后第一个星期二的日期 (在SQL中查找下一个星期几的日期),根据 DATEFIRST 的值可能需要调整最后一个值。
d
是同一周中 c
后第一个星期三的日期。
Cast(Sign(a - b) + 1 as bit)
如果 a
大于等于 b
则为 1,否则为 0。
(x + ABS(x)) / 2
如果 x 不是负数,则为 x
,否则为 0。
考虑到排除范围的经过时间的公式为:
+ (Exclusion Start - Start) If (Start < Exclusion Start)
- (Exclusion Start - End) If (End < Exclusion Start)
+ (End - Exclusion End) If (Exclusion End < End)