Это классическая c проблема "пробелов и островов", в которой вы пытаетесь определить границы своих островов, и которую вы можете решить с помощью некоторых оконных функций.
Ваше первоначальное усилие на пути. Вместо того чтобы получить следующую дату начала, я использовал предыдущую дату окончания для расчета группировок.
Самый внутренний подзапрос, приведенный ниже, получает предыдущую дату окончания для каждого из ваших диапазонов дат, а также назначает номер строки, который мы используем позже для поддержания порядка в наших группах.
В следующем подзапросе используется предыдущая конечная дата, чтобы определить, какие группы дат находятся в диапазоне go вместе (частично или полностью).
Самый внешний запрос - это конечный результат, который вы ищете.
SELECT
Grp.ID,
MIN(Grp.StartDate) AS GroupingStartDate,
MAX(Grp.EndDate) AS GroupingEndDate
FROM
(
SELECT
PrevDt.ID,
PrevDt.StartDate,
PrevDt.EndDate,
SUM(CASE WHEN DATEADD(DAY,1,PrevDt.PreviousEndDate) >= PrevDt.StartDate THEN 0 ELSE 1 END)
OVER (PARTITION BY PrevDt.ID ORDER BY PrevDt.RN) AS GrpNum
FROM
(
SELECT
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY StartDate, EndDate) as RN,
ID,
StartDate,
EndDate,
LAG(EndDate,1) OVER (PARTITION BY ID ORDER BY StartDate) AS PreviousEndDate
FROM
tbl
) AS PrevDt
) AS Grp
GROUP BY
Grp.ID,
Grp.GrpNum;
Результаты:
+-----+------------------+--------------+
| ID | InitialStartDate | FinalEndDate |
+-----+------------------+--------------+
| 001 | 2018-01-01 | 2018-03-01 |
| 001 | 2018-05-01 | 2018-06-01 |
+-----+------------------+--------------+
SQL Fiddle demo.
Дополнительная литература:
SQL Гапсов и островов в последовательностях
Пробелы и острова в диапазонах дат