根据订单对SQL结果进行分组

mat*_*hew 7 sql t-sql sql-server sql-server-2005 sql-server-2012

我有这样的数据表:

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
Run Code Online (Sandbox Code Playgroud)

我想对每组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
Run Code Online (Sandbox Code Playgroud)

我知道每个组开始和停止的唯一方法是RowNumber重新开始.我怎么能做到这一点?它还需要相当高效,因为我需要这样做的表有5200万行.

附加信息

ID是真正的顺序,但RowNumber可能不是.我认为RowNumber总是以1开头,但是例如group1的RowNumbers可以是"1,1,2,2,3,4",而group2则可以是"1,2,4,6"等.

Mar*_*ith 6

对于评论中澄清的要求

group1的rownumbers可以是"1,1,2,2,3,4",而对于group2,它们可以是"1,2,4,6"......较高的数字后跟较低的数字将是一个新组.

SQL Server 2012解决方案可能如下所示.

  1. 使用LAG访问前一行和标志设置为1,如果该行是一个新组或开始0不然.
  2. 计算这些标志的运行总和以用作分组值.

码

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
Run Code Online (Sandbox Code Playgroud)

SQL小提琴

假设ID是聚簇索引,对此的计划有一次扫描YourTable并避免任何排序操作.

计划