I would first work out where the islands are in your data set, and only after that, work out which ones are overlapped by your query ranges:
declare @t table (ID int,StartDate date,EndDate date)
insert into @t(ID,StartDate,EndDate) values
(1 ,'20140105','20140110'),
(2 ,'20140106','20140111'),
(3 ,'20140107','20140112'),
(4 ,'20140108','20140113'),
(5 ,'20140109','20140114'),
(6 ,'20140126','20140131'),
(7 ,'20140127','20140201'),
(8 ,'20140128','20140202'),
(9 ,'20140129','20140203'),
(10 ,'20140130','20140204')
declare @Start date
declare @End date
select @Start='20140106',@End='20140107'
;With PotIslands as (
--Find ranges which aren't overlapped at their start
select StartDate,EndDate from @t t where
not exists (select * from @t t2 where
t2.StartDate < t.StartDate and
t2.EndDate >= t.StartDate)
union all
--Extend the ranges by any other ranges which overlap on the end
select pi.StartDate,t.EndDate
from PotIslands pi
inner join
@t t
on
pi.EndDate >= t.StartDate and pi.EndDate < t.EndDate
), Islands as (
select StartDate,MAX(EndDate) as EndDate from PotIslands group by StartDate
)
select * from Islands i where @Start <= i.EndDate and @End >= i.StartDate
Result:
StartDate EndDate
---------- ----------
2014-01-05 2014-01-14
If you need the individual rows, you can now join the selected islands back to the @t
table for a simple range query.
This works because, for example, if any row within an island is ever included in a range, the entire remaining rows on an island will always also be included. So we find the islands first.