Sql 合并表中的子集
我在SQLServer2008中有一个表,其中包含以下格式的数据Sql 合并表中的子集,sql,sql-server,Sql,Sql Server,我在SQLServer2008中有一个表,其中包含以下格式的数据 UserID StartWeek EndWeek Type 1 1 3 A 1 4 5 A 1 6 10 A 1 11 13 B 1 14 16 A 2 1 5
UserID StartWeek EndWeek Type
1 1 3 A
1 4 5 A
1 6 10 A
1 11 13 B
1 14 16 A
2 1 5 A
2 6 9 A
2 10 16 B
我希望合并/压缩相邻的类型,以便生成的表如下所示
UserID StartWeek EndWeek Type
1 1 10 A
1 11 13 B
1 14 16 A
2 1 9 A
2 10 16 B
有人对实现这一目标的最佳方式有什么建议吗?我一直在考虑使用行数和分区,但我不能让它完全按照我所希望的那样运行。可能有一种更简洁的方法,但这会产生正确的结果
DECLARE @t TABLE
(UserId TINYINT
,StartWeek TINYINT
,EndWeek TINYINT
,TYPE CHAR(1)
)
INSERT @t
SELECT 1,1,3,'A'
UNION SELECT 1,4,5,'A'
UNION SELECT 1,6,10,'A'
UNION SELECT 1,11,13,'B'
UNION SELECT 1,14,16,'A'
UNION SELECT 2,1,5,'A'
UNION SELECT 2,6,9,'A'
UNION SELECT 2,10,16,'B'
;WITH srcCTE
AS
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY t1.UserID, t1.Type
ORDER BY t1.EndWeek
) AS rn
FROM @t AS t1
)
,recCTE
AS
(
SELECT *
,0 AS grp
FROM srcCTE
WHERE rn = 1
UNION ALL
SELECT s.UserId
,s.StartWeek
,s.EndWeek
,s.TYPE
,s.rn
,CASE WHEN s.StartWeek - 1 = r.EndWeek
THEN r.grp
ELSE r.grp+ 1
END AS GRP
FROM srcCTE AS s
JOIN recCTE AS r
ON r.UserId = s.UserId
AND r.TYPE = s.TYPE
AND r.rn = s.rn - 1
)
SELECT UserId
,MIN(StartWeek) AS StartWeek
,MAX(EndWeek) AS EndWeek
,TYPE
FROM recCTE AS s1
GROUP BY UserId
,TYPE
,grp
也使用CTE,但方式略有不同
DECLARE @Consolidate TABLE (
UserID INTEGER, StartWeek INTEGER,
EndWeek INTEGER, Type CHAR(1))
INSERT INTO @Consolidate VALUES (1, 1, 3, 'A')
INSERT INTO @Consolidate VALUES (1, 4, 5, 'A')
INSERT INTO @Consolidate VALUES (1, 6, 10, 'A')
INSERT INTO @Consolidate VALUES (1, 14, 16, 'A')
INSERT INTO @Consolidate VALUES (1, 11, 13, 'B')
INSERT INTO @Consolidate VALUES (2, 1, 5, 'A')
INSERT INTO @Consolidate VALUES (2, 6, 9, 'A')
INSERT INTO @Consolidate VALUES (2, 10, 16, 'B')
;WITH ConsolidateCTE AS
(
SELECT UserID, StartWeek, EndWeek, Type
FROM @Consolidate
UNION ALL
SELECT cte.UserID, cte.StartWeek, c.EndWeek, c.Type
FROM ConsolidateCTE cte
INNER JOIN @Consolidate c ON
c.UserID = cte.UserID
AND c.StartWeek = cte.EndWeek + 1
AND c.Type = cte.Type
)
SELECT UserID, [StartWeek] = MIN(Startweek), EndWeek, Type
FROM (
SELECT UserID, Startweek, [EndWeek] = MAX(EndWeek), Type
FROM ConsolidateCTE
GROUP BY UserID, StartWeek, Type
) c
GROUP BY UserID, EndWeek, Type
ORDER BY 1, 2, 3
@Oded:SQLServer9是SQLServer2005。干杯,它看起来可能没有其他解决方案那么优雅,但对我自己和我的其他队友来说,它更容易理解。