I have a table that holds a person id and a date range (a start date and a stop date). Each person may have multiple rows with multiple start and stop dates.
create table #DateRanges (
tableID int not null,
personID int not null,
startDate date,
endDate date
);
insert #DateRanges (tableID, personID, startDate, endDate)
values (1, 100, '2011-01-01', '2011-01-31') -- Just January
, (2, 100, '2011-02-01', '2011-02-28') -- Just February
, (3, 100, '2011-04-01', '2011-04-30') -- April - Skipped March
, (4, 100, '2011-05-01', '2011-05-31') -- May
, (5, 100, '2011-06-01', '2011-12-31') -- June through December
I need a way to collapse adjacent date ranges (where the end date of the previous row is exactly one day before the start date of the next). But it must include all contiguous ranges, splitting only when the end-to-start gap is greater than one day. The above data needs to be compressed to:
+-----------+----------+--------------+------------+
| SomeNewID | PersonID | NewStartDate | NewEndDate |
+-----------+----------+--------------+------------+
| 1 | 100 | 2011-01-01 | 2011-02-28 |
+-----------+----------+--------------+------------+
| 2 | 100 | 2011-04-01 | 2011-12-31 |
+-----------+----------+--------------+------------+
Just two rows because the only missing range is March. Now, if all of march were present, either as one row or many rows, the compression would result in just one row. But if only two days in the middle of March were present, we would get a 3rd row to show the March dates.
I've been working with LEAD and LAG functions in SQL 2016 to try to get this done as a recordset operation, but so far have come up empty. I would like to be able to do it without a loop and RBAR, but I'm not seeing a solution.