Thật khó để nói liệu giải pháp bên dưới có phù hợp với bạn hay không, dựa trên mẫu dữ liệu nhỏ, nhưng hy vọng nó sẽ giúp bạn bắt đầu.
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