SQL Server增加每个新唯一值的行号

时间:2017-06-21 08:34:00

标签: sql-server

我正在尝试获得如下结果:

1 foo 1-Jan
2 bar 2-Feb
3 baz 3-Mar
3 baz 4-Apr
3 baz 5-May
4 quz 6-Jun
4 quz 7-Jul

使用此T-SQL:

SELECT ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [DateTime]) AS [SetNum], *
FROM [ComplicatedQuery]

但相反,我得到了:

1 foo 1-Jan
1 bar 2-Feb
1 baz 3-Mar
2 baz 4-Apr
3 baz 5-May
1 quz 6-Jun
2 quz 7-Jul

如何更改它以增加每个新唯一值[ID]的行/集编号?

3 个答案:

答案 0 :(得分:1)

我会使用DENSE_RANK()代替ROW_NUMBER()

DENSE_RANK() OVER(ORDER BY [Column_with_foo_bar_baz_coco_jambo_etc]) AS Rnk

提示:查看documentation中的示例A. Ranking rows within a partitionenter image description here

答案 1 :(得分:0)

我们需要使用两个窗口聚合来实现您想要的结果 - 第一个确保为同一个ID的所有行分配一个值,然后在订购标准中使用:

declare @t table (Desired int,ID varchar(9),Dt datetime)
insert into @t(Desired,ID,Dt) values
(1,'foo','20170101'),
(2,'bar','20170202'),
(3,'baz','20170303'),
(3,'baz','20170404'),
(3,'baz','20170505'),
(4,'quz','20170606'),
(4,'quz','20170707')

;With MinDt as (
select *,MIN(Dt) OVER (PARTITION BY ID) as MinDt
from @t
)
select *,DENSE_RANK() OVER (ORDER BY MinDt,ID) as rk
from MinDt

结果:

Desired     ID        Dt                      MinDt                   rk
----------- --------- ----------------------- ----------------------- --------------------
1           foo       2017-01-01 00:00:00.000 2017-01-01 00:00:00.000 1
2           bar       2017-02-02 00:00:00.000 2017-02-02 00:00:00.000 2
3           baz       2017-03-03 00:00:00.000 2017-03-03 00:00:00.000 3
3           baz       2017-04-04 00:00:00.000 2017-03-03 00:00:00.000 3
3           baz       2017-05-05 00:00:00.000 2017-03-03 00:00:00.000 3
4           quz       2017-06-06 00:00:00.000 2017-06-06 00:00:00.000 4
4           quz       2017-07-07 00:00:00.000 2017-06-06 00:00:00.000 4

ID中包含DENSE_RANK,如果多个ID值具有相同的最小Dt值,则可以起到平局作用。

答案 2 :(得分:0)

SELECT Distinct Dense_Rank() OVER (ORDER BY ID) AS [SetNum], ID into #temp
FROM [ComplicatedQuery]


SELECT t.SetNum AS [SetNum], cq.* 
FROM [ComplicatedQuery] cq join #temp t on cq.ID=t.ID order by t.SetNum