DENSE_RANK() - 这里有什么问题?

DENSE_RANK() - What's wrong here?

我有一个很简单的table如下:

ID  NAME PRICE
1   A   10.45
2   B   8.25
3   A   10.45
4   C   5.00
5   D   4.00
6   E   10.45

当运行 DENSE_RANK()

select [name], [price], 
       DENSE_RANK() over (PARTITION BY [name], [price] ORDER BY [name],[price]) as drank
  from temp

我明白了。我希望看到第二行应该有 drank of 2

name price  drank
A   10.45   1
A   10.45   1  //this should be 2, isn't
B   8.25    1
C   5.00    1
D   4.00    1
E   10.45   1

如果要枚举具有唯一编号的行,请使用row_number():

select [name], [price], 
       row_number() over (PARTITION BY [name], [price] ORDER BY (SELECT NULL)) as drank
from temp;

这里的问题是你对排名函数的误解。来自 DENSE_RANK (Transact-SQL)

Remarks

If two or more rows have the same rank value in the same partition, each of those rows will receive the same rank.

RANK也是如此。这意味着,对于您的数据,由于 nameprice 具有相同的值,因此它们被赋予相同的等级;在这种情况下 1这两个函数的区别在于它们处理相等行之后的行的方式。 DENSE_RANK 将为每个“新”等级依次递增,而 RANK 将跳过具有相等行的排名。 IE。分别为 1,1,2,3 和 1,1,3,4。

您显然想要的是 ROW_NUMBER。但是,我确实注意到,按相同的列进行分区和排序通常也是一个缺陷,因为首先对行进行编号是任意的,并且每次的任意编号可能都不相同。理想情况下,您应该按提供明确顺序的另一列进行排序;也许是一个 ID:

SELECT name,
       price,
       ROW_NUMBER() OVER (PARTITION BY name, price ORDER BY SomeOtherColumn) AS RN
FROM dbo.YourTable;

如果您没有要排序的列,您可以使用任意值,甚至 (SELECT NULL) 正如 Gordon 在他们的回答中所做的那样。