データ サンプルが小さいため、以下のソリューションがうまくいくかどうかはわかりませんが、うまくいけば、開始するのに役立ちます。
IF OBJECT_ID('tempdb..#sked') is not null DROP TABLE #sked IF OBJECT_ID('tempdb..#tmpResults') is not null DROP TABLE #tmpResults create table #sked( ID int, time_start datetime2, time_end datetime2, duration int) insert into #sked (ID,time_start,time_end,duration) values (4,'2016-06-06 00:30:00','2016-06-06 01:30:00',3600000), (2,'2016-06-06 04:00:00','2016-06-06 04:20:00',1200000), (1,'2016-06-06 10:00:00','2016-06-06 11:00:00',3600000), (6,'2016-06-06 11:30:00','2016-06-06 12:30:00',3600000) declare @startRange datetime2 declare @endRange datetime2 declare @slotDurationInMinutes int set @startRange = '2016-06-05T00:00:00.000' set @endRange = '2016-06-07T21:59:00.000' set @slotDurationInMinutes = 30 select time_end as free_from, isnull(lead(time_start) over (order by time_end),@endRange) as free_until into #tmpResults from #sked where time_end >= @startRange and time_end <= @endRange --and duration <= (@slotDurationInMinutes * 60000) --conversion to milliseconds union all select case when @startRange < min(time_start) then @startRange end as free_from, case when @startRange < min(time_start) then min(time_start) end as free_until from #sked where time_end >= @startRange and time_end <= @endRange --and duration <= (@slotDurationInMinutes * 60000) --conversion to milliseconds order by free_from select *, DATEDIFF(minute,free_from,free_until) from #tmpResults where free_from is not null and DATEDIFF(minute,free_from,free_until) >= @slotDurationInMinutes
プレ>