T-SQL中DENSE_RANK函数返回异常排名值的问题咨询
看起来你遇到了DENSE_RANK排名不符合预期的问题——明明逻辑上应该是连续的排名,却出现了缺号的情况。别担心,这其实是对DENSE_RANK函数的工作机制理解不到位导致的,我来帮你拆解原因:
DENSE_RANK的排名基于全部分区数据,而非你展示的结果子集
你的查询逻辑是先从原表##Table生成包含ColC的子查询,再对这个子查询的所有行计算DENSE_RANK。也就是说,排名的计算是基于子查询返回的每一行,而不是你最终展示的那几行。举个例子,你看到
ValueA的第一个行排名是3,说明在ColC='ValueA+01/11/2017'这个分区里,存在两个不同的ColB值比01/11/2017 14:06更早,这些行确实存在于原表中,但没有出现在你给出的结果集里(可能是你只截取了部分结果,或者有隐含的过滤逻辑没写出来)。同理,排名中缺失的4,说明在01/11/2017 14:06和01/11/2017 16:06之间,还有一个不同的ColB值对应的行,同样没被展示出来。DENSE_RANK的连续是指“不同排序值的排名连续”,而非结果行的排名连续
要明确DENSE_RANK的核心规则:在同一个分区内,相同的排序值(这里是ColB)会得到相同的排名,而每出现一个新的排序值,排名就递增1(不会跳过数字)。但如果某些行没有出现在你的结果展示中,对应的排名就会看起来“缺失”,但实际上这些排名是分配给了那些未被展示的行。
你可以运行下面的查询验证这个结论,查看ValueA分区的所有行和对应的排名:
SELECT ColB, ColC, DENSE_RANK() OVER(PARTITION BY ColC ORDER BY ColB) AS [Rank] FROM ( SELECT *, concat(ColA, CONVERT(DATE, ColB)) AS ColC FROM ##Table ) Subquery1 WHERE ColC LIKE 'ValueA%' -- 过滤出ValueA对应的分区 ORDER BY ColB;
执行后你就能看到所有行的排名,那些“缺失”的排名对应的行就会清晰显示出来。
内容的提问来源于stack exchange,提问作者Statsanalyst

