T-SQL “dense_rank” with a maximum number of rows with each rank

倖福魔咒の 提交于 2020-01-04 07:18:08

问题


If I do a

dense_rank() over (order by colname),

I get the same rank for all rows with the same value in the column colname.

However, I want to limit the number of rows with the same rank to @maxrows so that when @maxrows rows have the same value in colname, a new rank is assigned to the next row even if the value of colname is still the same.

How can I achieve this?


回答1:


You can achieve this via using several ranking functions. We use ROW_NUMBER() in the middle and another column to perform tie-breaking:

declare @maxRows int
set @maxRows = 5

; With InitialRanks as (
    select DENSE_RANK() OVER (ORDER BY type) as rnk,* from sys.objects
), OrderedRanks as (
    select (ROW_NUMBER() OVER (PARTITION BY rnk ORDER by object_id)-1)
            / @maxRows as rn,*
    from InitialRanks
)
select DENSE_RANK() OVER (ORDER BY rnk,rn),* from OrderedRanks

Here I get only up to 5 columns with each (final) rank value. The ranking is based on type but we use object_id as a secondary column to work out the order in which rows are allowed a particular rank.


Turns out I'd over-complicated the above - there's no need for the first CTE and the first DENSE_RANK since that's effectively acting as a proxy for the type column in the ROW_NUMBER() function - so why not just use the type column directly and simplify things:

declare @maxRows int
set @maxRows = 5

; With  OrderedRanks as (
    select (ROW_NUMBER() OVER (PARTITION BY type ORDER by object_id)-1)
            / @maxRows as rn,*
    from sys.objects
)
select DENSE_RANK() OVER (ORDER BY type,rn),* from OrderedRanks


来源:https://stackoverflow.com/questions/20656848/t-sql-dense-rank-with-a-maximum-number-of-rows-with-each-rank

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!