SQL Server NTILE - 不同四分位数中的相同值

eme*_*ava 7 sql-server sql-server-2008

我有一个场景,我使用下面的 SQL Server NTILE 函数将多个结果拆分为四分位数。目标是每个类中的行数相同

case NTILE(4) over (order by t2.TotalStd) 
   when 1 then 'A' when 2 then 'B' when 3 then 'C' else 'D' end as Class
Run Code Online (Sandbox Code Playgroud)

结果表如下所示,A、B、C 和 D 4 个班级组之间有 (9,9,8,8) 拆分。

有两个结果给我带来了问题,两行的总 std 值相同,为 30,但分配给不同的四分位数。

8   30  A
2   30  B
Run Code Online (Sandbox Code Playgroud)

我想知道有没有办法确保将具有相同值的行分配给相同的四分位数?我可以按另一列分组或分区以获得这种行为吗?

Pos TotalStd    class
1   16  A
2   23  A
3   21  A
4   29  A
5   25  A
6   26  A
7   28  A
8   30  A
9   29  A
1   31  B
2   30  B
3   32  B
4   32  B
5   34  B
6   32  B
7   34  B
8   32  B
9   33  B
1   36  C
2   35  C
3   35  C
4   35  C
5   40  C
6   38  C
7   41  C
8   43  C
1   43  D
2   48  D
3   45  D
4   47  D
5   44  D
6   48  D
7   46  D
8   57  D
Run Code Online (Sandbox Code Playgroud)

Roe*_*uar 8

您将需要使用 rank 函数重新创建 Ntile 函数。rank 函数为具有相同值的行提供相同的等级。该值稍后“跳转”到下一个等级,就像您使用 row_number 一样。我们可以使用这种行为来模拟 Ntile 函数,强制它为具有相同值的行提供相同的 Ntile 值。但是 - 这将导致 Ntile 分区具有不同的大小。请参阅下面使用 4 个 bin 的新 Ntile 示例:

declare @data table ( x int )

insert @data values 
(1),(2),
(2),(3),
(3),(4),
(4),(5)

select  
    x,
    1+(rank() over (order by x)-1) * 4 / count(1) over (partition by (select 1)) as new_ntile
from @data
Run Code Online (Sandbox Code Playgroud)

结果:

x   new_ntile
---------------
1   1
2   1
2   1
3   2
3   2
4   3
4   3
5   4
Run Code Online (Sandbox Code Playgroud)