Я не думаю, что это возможно без использования временной таблицы. (Вы не исключаете их использования, но не исключали и использование курсоров, пока Майк Беннетт не опубликовал свой ответ)
Я достаточно уверен, что это универсальное решение - оно использует недокументированную функцию, позволяющую изменять значение переменной более одного раза во время оператора обновления.
Вы можете пропустить создание столбца искусственной идентификации, чтобы гарантировать порядок (autoID в моем запросе), если записи в вашей таблице введены в порядке обновления.
-- Setup test data
IF object_id('tempdb..#test1') IS NOT NULL
DROP TABLE #test1
GO
CREATE TABLE #test1
(id INT
,effdate DATETIME
,termdate DATETIME
)
INSERT #test1
SELECT 1,'2007-05-01','2007-05-31'
UNION SELECT 2 ,'2007-06-01','2007-06-30'
UNION SELECT 3 ,'2007-07-01','2007-09-30'
UNION SELECT 4 ,'2008-03-01','2008-03-31'
UNION SELECT 5 ,'2008-05-01','2008-05-31'
UNION SELECT 6 ,'2008-06-01','2008-06-30'
GO
IF object_id('tempdb..#t') IS NOT NULL
DROP TABLE #t
GO
-- Order the records by effdate
SELECT IDENTITY(INT,1,1) AS autoId
,cast(NULL AS INT) groupID
,*
INTO #t
FROM #test1
ORDER BY effdate
UPDATE #t
SET groupID = 1
WHERE autoID = 1
DECLARE @gp INT
SET @gp = 1
--update groupID using the undocumented variable-update method
UPDATE t2
SET @gp = CASE WHEN t1.termdate = t2.effdate - 1
THEN @gp
ELSE @gp + 1
END
,groupID = @gp
FROM #t AS t1
JOIN #t AS t2
ON t1.autoID = t2.autoID - 1
--output results
select min(effdate), max(termdate)
from #t
group by groupID
order by groupID