Reputation: 4356
I'm trying to get results like the following:
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
with this T-SQL:
SELECT ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [DateTime]) AS [SetNum], *
FROM [ComplicatedQuery]
But instead I'm getting:
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
How can I change it to increment the row/set number for each new unique value of [ID]
?
Upvotes: 0
Views: 3182
Reputation: 447
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
Upvotes: 0
Reputation: 1
I would use DENSE_RANK()
instead of ROW_NUMBER()
thus:
DENSE_RANK() OVER(ORDER BY [Column_with_foo_bar_baz_coco_jambo_etc]) AS Rnk
Tip: look at example A. Ranking rows within a partition
from documentation:
Upvotes: 1
Reputation: 239824
We need to use two windowed aggregates to achieve your desired results - the first ensures that all rows for the same ID
get assigned a single value to then use in the ordering criteria:
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
Results:
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
The inclusion of ID
in the DENSE_RANK
is to act as a tie-breaker in case multiple ID
values have the same minimal Dt
value.
Upvotes: 0