我想在MS-SQL中创建一个查询,以创建一个包含递增组号的列。
这就是我希望我的数据返回的方式:
Column 1 | Column 2 | Column 3
------------------------------
I | 1 | 1
O | 2 | 2
O | 2 | 3
I | 3 | 4
O | 4 | 5
O | 4 | 6
O | 4 | 7
O | 4 | 8
I | 5 | 9
O | 6 | 10
Column 1
是I
,O
表示In和Out。Column 2
是行组(在Column 1
更改时应该增加)。Column 3
是行号。那么如何编写查询以便Column 2
每次Column 1
更改时都会递增?
答案 0 :(得分:1)
首先,要执行此类操作,您需要一些可以识别行顺序的列。如果您有一个确定此顺序的列,例如标识列,则可以使用它来执行以下操作:
可运行的示例:
CREATE TABLE #Groups
(
id INT IDENTITY(1, 1) , -- added identity to provide order
Column1 VARCHAR(1)
)
INSERT INTO #Groups
( Column1 )
VALUES ( 'I' ),
( 'O' ),
( 'O' ),
( 'I' ),
( 'O' ),
( 'O' ),
( 'O' ),
( 'O' ),
( 'I' ),
( 'O' );
;
WITH cte
AS ( SELECT id ,
Column1 ,
1 AS Column2
FROM #Groups
WHERE id = 1
UNION ALL
SELECT g.id ,
g.Column1 ,
CASE WHEN g.Column1 = cte.Column1 THEN cte.Column2
ELSE cte.Column2 + 1
END AS Column2
FROM #Groups g
INNER JOIN cte ON cte.id + 1 = g.id
)
SELECT *
FROM cte
OPTION (MAXRECURSION 0) -- required to allow for more than 100 recursions
DROP TABLE #Groups
如果Column2
中的值发生变化,此代码会有效地遍历记录,将每一行与下一行进行比较并递增Column1
的值。
如果您没有标识列,则可以考虑添加标识列。
来自@AeroX:
对于30K记录,最后一行:OPTION (MAXRECURSION 0)
需要在使用Common Table Expression (CTE)时覆盖默认的100次递归。将其设置为0
,意味着它不受限制。
答案 1 :(得分:1)
如果您有sqlserver 2012 +
,这将有效DECLARE @t table(col1 char(1), col3 int identity(1,1))
INSERT @t values
('I'), ('O'), ('O'), ('I'), ('O'), ('O'), ('O'), ('O'), ('I'), ('O')
;WITH CTE AS
(
SELECT
case when lag(col1) over (order by col3) = col1
then 0 else 1 end increase,
col1,
col3
FROM @t
)
SELECT
col1,
sum(increase) over (order by col3) col2,
col3
FROM CTE
结果:
col1 col2 col3
I 1 1
O 2 2
O 2 3
I 3 4
O 4 5
O 4 6
O 4 7
O 4 8
I 5 9
O 6 10