私がこれを解決する一般的な方法は次のとおりです。
;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
、互いに隣接する複数の間隔になる可能性があります)