我有这样的数据表:
ID | RowNumber | Data
------------------------------
1 | 1 | Data
2 | 2 | Data
3 | 3 | Data
4 | 1 | Data
5 | 2 | Data
6 | 1 | Data
7 | 2 | Data
8 | 3 | Data
9 | 4 | Data
我想对每组 RowNumbers 进行分组,以便我的结果是这样的:
ID | RowNumber | Group | Data
--------------------------------------
1 | 1 | a | Data
2 | 2 | a | Data
3 | 3 | a | Data
4 | 1 | b | Data
5 | 2 | b | Data
6 | 1 | c | Data
7 | 2 | c | Data
8 | 3 | c | Data
9 | 4 | c | Data
我知道每个组从哪里开始和停止的唯一方法是 RowNumber 重新开始时。我怎样才能做到这一点?它也需要相当高效,因为我需要在其上执行此操作的表有 5200 万行。
附加信息
ID 确实是连续的,但 RowNumber 可能不是。我认为 RowNumber 将始终以 1 开头,但例如 group1 的 RowNumbers 可能是“1,1,2,2,3,4”,而对于 group2,它们可能是“1,2,4,6”等。
最佳答案
对于评论中明确的要求
SQL Server 2012 解决方案可能如下所示。
LAG
访问前一行,如果该行是新组的开始,则为 1
设置一个标志,否则为 0
。 代码
WITH T1 AS
(
SELECT *,
LAG(RowNumber) OVER (ORDER BY ID) AS PrevRowNumber
FROM YourTable
), T2 AS
(
SELECT *,
IIF(PrevRowNumber IS NULL OR PrevRowNumber > RowNumber, 1, 0) AS NewGroup
FROM T1
)
SELECT ID,
RowNumber,
Data,
SUM(NewGroup) OVER (ORDER BY ID
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM T2
SQL Fiddle
假设
ID
是聚集索引,该计划对 YourTable
进行一次扫描并避免任何排序操作。