Я бы решил это с помощью рекурсии. Хотя это, конечно, очень тяжело, в нем должны учитываться даже самые сложные тайминги аккаунта (при условии, что ваши данные имеют такой). Однако, если предоставленные образцы данных настолько сложны, насколько вам необходимо решить, я настоятельно рекомендую придерживаться решения, представленного выше. Это гораздо более кратко и ясно.
WITH x (cust_id, open_date, closed_date, lvl, grp) AS (
SELECT cust_id, open_date, closed_date, 1, 1
FROM (
SELECT cust_id
, open_date
, closed_date
, row_number()
OVER (PARTITION BY cust_id ORDER BY closed_date DESC, open_date) AS rn
FROM cust
) AS t
WHERE rn = 1
UNION ALL
SELECT cust_id, open_date, closed_date, lvl, grp
FROM (
SELECT c.cust_id
, c.open_date
, c.closed_date
, x.lvl + 1 AS lvl
, x.grp + CASE WHEN c.closed_date < x.open_date THEN 1 ELSE 0 END AS grp
, row_number() OVER (PARTITION BY c.cust_id ORDER BY c.closed_date DESC) AS rn
FROM cust c
JOIN x
ON x.cust_id = c.cust_id
AND c.open_date < x.open_date
) AS t
WHERE t.rn = 1
)
SELECT cust_id, min(open_date) AS first_open_date, max(closed_date) AS last_closed_date
FROM x
GROUP BY cust_id, grp
ORDER BY cust_id, grp
Я бы также добавил предостережение, которое я не запускаю на SQL Сервере, поэтому могут быть различия в синтаксисе, которые я не учел. Надеюсь, они незначительные, если они есть.