[英]Grouping SQL Results based on order
我有這樣的數據表:
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”等。
對於評論中澄清的要求
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
假設ID
是聚集索引,則此計划對YourTable
一次掃描,並避免任何排序操作。
如果id是真正的順序,你可以這樣做:
select t.*,
(id - rowNumber) as grp
from t
您也可以使用遞歸CTE
;WITH cte AS
(
SELECT ID, RowNumber, Data, 1 AS [Group]
FROM dbo.test1
WHERE ID = 1
UNION ALL
SELECT t.ID, t.RowNumber, t.Data,
CASE WHEN t.RowNumber != 1 THEN c.[Group] ELSE c.[Group] + 1 END
FROM dbo.test1 t JOIN cte c ON t.ID = c.ID + 1
)
SELECT *
FROM cte
在SQLFiddle上演示
怎么樣:
select ID, RowNumber, Data, dense_rank() over (order by grp) as Grp
from (
select *, (select min(ID) from [Your Table] where ID > t.ID and RowNumber = 1) as grp
from [Your Table] t
) t
order by ID
這應該適用於SQL 2005.如果您不關心連續數字,也可以使用rank()。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.