Я не нашел другой возможности, кроме как использовать CURSOR. Теперь вы можете проверить новый вывод, указанный ниже, с вашими новыми предоставленными данными. Мне вывод кажется правильным.
DECLARE @tbl TABLE (cid INT, st_date INT, end_date INT )
DECLARE @tmp TABLE (cid INT, st_date INT, end_date INT, gid INT )
DECLARE @gid INT
SET @gid = 1
INSERT INTO @tbl (cid, st_date,end_date)
VALUES
(1,20190110,20190111),
(1,20190111,20190117),
(1,20190117,20190123),
(2,20190101,20190117),
(2,20190119,20190123),
(2,20190123,20190127),
(2,20190201,20190205),
(2,20190205,20190210)
DECLARE @cid INT, @st_date INT, @end_date INT,@B_cid INT,@B_st_date INT
DECLARE vendor_cursor CURSOR FOR
SELECT A.cid,A.st_date,A.end_date,B.cid B_cid,B.st_date B_st_date
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY CID,st_date,end_date) RN,*
FROM
(
SELECT CID,CONVERT(varchar, st_date, 23) st_date,CONVERT(varchar, end_date, 23) end_date FROM @tbl
)X
)A
LEFT JOIN (
SELECT ROW_NUMBER() OVER (ORDER BY CID,st_date,end_date)-1 RN,*
FROM
(
SELECT CID,CONVERT(varchar, st_date, 23) st_date,CONVERT(varchar, end_date, 23) end_date FROM @tbl
)Y
)B
ON A.RN = B.RN
ORDER BY 1,2
OPEN vendor_cursor
FETCH NEXT FROM vendor_cursor
INTO @cid, @st_date,@end_date,@B_cid,@B_st_date
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@cid = @B_cid) AND (@end_date = @B_st_date)
BEGIN
INSERT INTO @tmp (cid, st_date,end_date,gid)
VALUES
(@cid,@st_date,@end_date,@gid)
END
ELSE
BEGIN
INSERT INTO @tmp (cid, st_date,end_date,gid)
VALUES
(@cid,@st_date,@end_date,@gid)
SET @gid = @gid +1
END
FETCH NEXT FROM vendor_cursor
INTO @cid, @st_date,@end_date,@B_cid,@B_st_date
END
CLOSE vendor_cursor;
DEALLOCATE vendor_cursor
SELECT cid,
MIN(st_date) st_date,
MAX(end_date) end_date
FROM @tmp
GROUP BY cid,gid
Новый вывод -
cid st_date end_date
1 20190110 20190123
2 20190101 20190117
2 20190119 20190127
2 20190201 20190210