一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

SQL中ROW_NUMBER与RANK函数在处理排名时有何区别?

时间:2026-07-21 09:45:54 编辑:袖梨 来源:一聚教程网

ROW_NUMBER()为每行分配唯一序号,不考虑值重复;RANK()对相同值赋予相同排名并跳过后续名次;DENSE_RANK()则不跳号;三者均需OVER(ORDER BY...),选择取决于是否需要保留并列语义。

ROW_NUMBER() 会强行给每行分配唯一序号,哪怕排序值相同

它不管字段值是否重复,只按 ORDER BY 的顺序从 1 开始硬编号。比如两条记录的 salary 都是 8000,ROW_NUMBER() 仍会返回 2 和 3 —— 这不是“错”,而是设计如此。

  • 必须搭配 OVER(),且 ORDER BY 是必需项;不写 PARTITION BY 就全表编号
  • 常用于分页(WHERE rn BETWEEN 11 AND 20)或取每组最新一条(WHERE rn = 1
  • 如果排序字段有重复,结果可能不稳定 —— 建议在 ORDER BY 后加一个唯一列(如 id)保证确定性

RANK() 对相同值赋予相同排名,并跳过后续名次

当遇到并列时,RANK() 不会“挤占”位置:两个并列第 2 名,下一个就是第 4 名,中间的第 3 名被跳过。这符合体育比赛、考试总分排名等现实逻辑。

  • 同样依赖 OVER(ORDER BY ...),语法结构和 ROW_NUMBER() 完全一致
  • 适合“取出所有最高分员工”这类需求 —— WHERE rk = 1 能拿到全部并列第一的记录
  • 注意:跳号行为只在有重复值时才显现;若所有排序字段值都不同,RANK()ROW_NUMBER() 输出完全一样

选哪个?关键看你要不要保留并列语义

这不是性能或兼容性问题,而是业务意图判断:

  • 要唯一行号、做分页、去重取首条 → 用 ROW_NUMBER()
  • 要真实反映“并列第 N 名”、允许同名次多行 → 用 RANK()
  • 如果还嫌 RANK() 跳号太跳跃(比如想让并列第 2 名之后是第 3 名),那就换 DENSE_RANK()

真正容易被忽略的是:三个函数在语法上几乎一模一样,仅靠名字区分;一旦写错,结果偏差往往不明显,直到上线后查数据才发现“怎么少了一条并列记录”或者“分页错位了”。

热门栏目