SQL Server里那些排名函数到底怎么用,弄懂它们其实没那么难
- 问答
- 2026-01-08 15:16:03
- 5
很多刚开始用SQL Server的朋友,一看到ROW_NUMBER、RANK、DENSE_RANK、NTILE这些排名函数就有点头大,感觉它们长得差不多,用起来又怕搞混,只要理解了它们核心的区别,用起来非常简单,今天我们就用大白话把它们讲清楚。
想象一个场景:你们班进行了一次考试,现在有一张成绩表,里面有学生姓名和分数,老师想看看大家的排名情况,这时候排名函数就派上用场了。
我们来认识第一个,也是最常用的:ROW_NUMBER()
这个名字直译过来就是“行号”,它的作用最简单:就是不管三七二十一,按照你指定的顺序,给每一行一个唯一的、连续的号码,从1开始。
我们按分数从高到低排名:
SELECT 学生姓名, 分数, ROW_NUMBER() OVER (ORDER BY 分数 DESC) AS 排名 FROM 成绩表
结果可能是: 小明 100分 排名1 小红 98分 排名2 小刚 98分 排名3 小丽 95分 排名4
你看,即使小红和小刚都是98分,并列第二,但ROW_NUMBER()很“死板”,它必须给出不一样的号码,所以硬是给了小刚一个第3名,它只关心行的顺序,不关心值是否相同。
那如果我想让分数一样的同学并列排名呢?这时候就要用RANK()了
RANK函数就智能多了,它会考虑值是否相同,如果值相同,就给它们相同的排名。
还用同样的数据和排序:
SELECT 学生姓名, 分数, RANK() OVER (ORDER BY 分数 DESC) AS 排名 FROM 成绩表
结果会变成: 小明 100分 排名1 小红 98分 排名2 小刚 98分 排名2 -- 注意,这里和小红并列第2了 小丽 95分 排名4 -- 注意!排名直接跳到了第4
RANK的规则是:并列的排名会占用名次,小红和小刚并列第二,他们俩就把第二名这个位置给“占”了,下一个分数不同的人(小丽)就只能排到第4名(因为第3名已经被“跳过”了)。
我们觉得跳过名次不太直观,希望排名是连续的,这时候DENSE_RANK()就登场了
DENSE_RANK翻译过来是“密集排名”,它也会让相同的值并列,但不会跳过名次。
同样的情况:
SELECT 学生姓名, 分数, DENSE_RANK() OVER (ORDER BY 分数 DESC) AS 排名 FROM 成绩表
结果: 小明 100分 排名1 小红 98分 排名2 小刚 98分 排名2 -- 依然并列第2 小丽 95分 排名3 -- 看这里!排名是连续的3,没有跳过
DENSE_RANK的好处是排名数字是连续的,更符合我们一些日常数数的习惯。
简单总结一下这三个核心函数的区别:
- ROW_NUMBER():连续唯一,不并列,像报数1,2,3,4...
- RANK():并列,但会跳过后续名次,像比赛颁奖,有并列冠军,就没有亚军,下一个是季军。
- DENSE_RANK():并列,且不跳名次,排名数字连续,像“第一梯队”、“第二梯队”这种分组。
别忘了重要的PARTITION BY
上面我们都是在整个班级(整张表)里排名,但OVER子句里还有一个超级有用的东西叫PARTITION BY,意思是“按...分组”,你可以把它理解成“先分组,再在组内排名”。
成绩表里还有班级列,我们想看看每个班级内部的排名:
SELECT 班级, 学生姓名, 分数, ROW_NUMBER() OVER (PARTITION BY 班级 ORDER BY 分数 DESC) AS 班级内排名 FROM 成绩表
这个查询会先按班级把学生分开(比如一班和二班),然后在一班内部按分数从高到低排1,2,3...,在二班内部再重新从1开始排1,2,3...。PARTITION BY和ORDER BY组合在一起,构成了排名函数完整的逻辑。
我们看一眼NTILE()
这个函数有点特别,它不完全是排名,更像是“分桶”或“分组”,你需要告诉它你想分成多少份(N份)。
老师想根据成绩把全班同学分成4个梯队(比如前25%是第一梯队,接着25%是第二梯队...):
SELECT 学生姓名, 分数, NTILE(4) OVER (ORDER BY 分数 DESC) AS 梯队 FROM 成绩表
NTILE(4)会尽量平均地把所有学生分成4组,并给每个学生标上他属于第几组(1到4),如果总人数不能被4整除,那么多出来的人会依次放在前面的组里。
实际应用小提示
这些排名函数特别有用,经常用来解决一些棘手的问题,
- 删除重复数据:用
ROW_NUMBER() PARTITION BY重复的字段,然后删除排名大于1的记录,可以保留唯一数据。 - 查询每个分组的前N名:比如查询每个部门工资最高的3个人,用
ROW_NUMBER() PARTITION BY 部门,然后外面套一个查询,筛选排名<=3就行。 - 数据分页:
ROW_NUMBER()是实现分页查询的经典方法。
SQL Server这几个排名函数的核心就是OVER子句里的ORDER BY(决定顺序)和PARTITION BY(决定分组),只要抓住ROW_NUMBER(不并列)、RANK(并列跳号)、DENSE_RANK(并列连续)这三个的本质区别,再多加练习,你就能轻松驾驭它们了。

本文由盈壮于2026-01-08发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/76881.html
