我有这样的数据表:

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 进行一次扫描并避免任何排序操作。

    sql - 根据顺序对 SQL 结果进行分组-LMLPHP

    10-08 08:21