我有第一个表格,其中包含已定义的工作时间:FreeTimes table (start datetime, end datetime)
和第二个已计划任务的表格:TaskTime table (start datetime, end datetime)
。
我需要以某种方式从第一个表中减去第二个表,所以我在这种条件下得到了一个自由时间的结果集:
答案 0 :(得分:2)
我解决这个问题的一般方法如下:
;With AllTimes as (
select [Start] as EventTime from FreeTimes
union
select [End] from FreeTimes
union
select [Start] from TaskTimes
union
select [End] from TaskTimes
), OrderedTimes as (
select EventTime,ROW_NUMBER() OVER (ORDER BY EventTime) rn
from AllTimes
), Intervals as (
select
ot1.EventTime as StartTime,
ot2.EventTime as EndTime
from
OrderedTimes ot1
inner join
OrderedTimes ot2
on
ot1.rn = ot2.rn - 1
)
select * from Intervals i
where not exists (
select * from TaskTimes T where --Overlapped
T.[Start] < i.EndTime and
T.[End] > i.StartTime)
and exists (
select * from FreeTimes T where
T.[Start] < i.EndTime and
T.[End] > i.StartTime)
我们基本上对所有感兴趣的日期时间值进行排序,然后对于每对连续值,如果与TaskTimes
表有一些重叠,则计算出来。如果有,则该对不应该在最终结果中。 (编辑 - 我们还必须检查区间对是否确实与FreeTimes
重叠)
如果需要,您可以更进一步并合并间隔(如果FreeTimes
中有重叠的行,您可能最终会有多个彼此相邻的间隔)