跳到主要内容

DENSE_RANK 窗口函数详解

一、一句话理解

DENSE_RANK()RANK() 一样给相同值分配相同排名,但不跳过后续排名——例如 1、1、2、3。

二、函数语法

DENSE_RANK() OVER (PARTITION BY 分组列 ORDER BY 排序列)

三、真实业务场景

场景:各部门薪资 Top 3(含并列)

查询每个部门薪资前3高的员工,并列的都算。

SELECT dept, name, salary
FROM (
SELECT dept, name, salary,
DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn
FROM employee
) t
WHERE rn <= 3;

示例数据

+----------+--------+--------+
| dept | name | salary |
+----------+--------+--------+
| 技术部 | 张三 | 50000 |
| 技术部 | 李四 | 45000 |
| 技术部 | 王五 | 45000 |
| 技术部 | 赵六 | 40000 |
| 技术部 | 钱七 | 40000 |
+----------+--------+--------+

结果

技术部: 张三(1), 李四(2), 王五(2), 赵六(3), 钱七(3)
→ 前3名包含5人,因为第2和第3各有并列

如果用 ROW_NUMBER,只会严格取到张三、李四、王五(因为编号不并列,赵六编号4被排除)。用 DENSE_RANK,排名 1/2/3 的所有人都被包含——这是面试中的高频陷阱题。

四、三种排名函数对比速查

函数并列跳号适用场景
ROW_NUMBER严格取 N 条、去重
RANK奥运奖牌排名
DENSE_RANK各部门 Top N(含并列)

五、常见坑点

坑1:DENSE_RANK vs RANK 的"前 N 名"陷阱

面试官问"取前3名",你用 RANK → 可能只返回2个人。用 DENSE_RANK → 可能返回5个人。必须先和面试官确认:并列的算不算、要不要严格限定人数。

六、面试怎么考

  • "DENSE_RANK 和 RANK 的区别是什么?" → 必考,回答"并列跳号 vs 并列不跳号"
  • "为什么前3名返回了5条数据?" → DENSE_RANK,并列不跳号
  • "什么场景用 DENSE_RANK 而不是 ROW_NUMBER?" → 需要并列排名且不允许跳过

七、相关面试题

📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

备注「数据仓库技术」加入社群,每日一道大厂SQL真题

交流微信二维码

你可能还想看