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?" → 需要并列排名且不允许跳过
七、相关面试题
- 13. 每个部门工资前3高的员工 — DENSE_RANK + PARTITION BY
- 03. 公会成员活跃度排名 — DENSE_RANK 连续排名
- 更多窗口函数面试题 →
📱关注公众号
「数据仓库技术」文章同步更新,不错过每一篇干货

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