Możesz skorzystać z obu funkcje okien
oraz użycie pojęcia o nazwie gaps-and-islands
. W twoim przypadku sąsiednie daty to wyspa, a luki są oczywiste.
Napisałem poniżej odpowiedź w sposób wyczerpujący, aby wyjaśnić, co robi zapytanie, ale najprawdopodobniej może być napisany w inny, bardziej zwięzły sposób. Proszę zobaczyć moje komentarze w odpowiedzi wyjaśniające, co robi każdy krok (podzapytanie).
--Determine Final output
select min(c.StartDate) as StartDate
, max(c.EndDate) as EndDate
from (
--Assign a number to each group of Contiguous Records
select b.ID
, b.StartDate
, b.EndDate
, b.EndDatePrev
, b.IslandBegin
, sum(b.IslandBegin) over (order by b.ID asc) as IslandNbr
from (
--Determine if its Contiguous (IslandBegin = 1, means its not Contiguous with previous record)
select a.ID
, a.StartDate
, a.EndDate
, a.EndDatePrev
, case when a.EndDatePrev is NULL then 1
when datediff(d, a.EndDatePrev, a.StartDate) > 1 then 1
else 0
end as IslandBegin
from (
--Determine Prev End Date
select tt.ID
, tt.StartDate
, tt.EndDate
, lag(tt.EndDate, 1, NULL) over (order by tt.ID asc) as EndDatePrev
from dbo.Table_Name as tt
) as a
) as b
) as c
group by c.IslandNbr
order by c.IslandNbr