【rownumber和rank区别】在SQL查询中,`ROW_NUMBER()` 和 `RANK()` 是两个常用的窗口函数,它们都可以对结果集进行排序并为每一行分配一个序号。虽然它们的用途相似,但在实际使用中存在一些关键的区别。以下是对这两个函数的详细对比总结。
一、基本定义
| 函数名 | 功能说明 |
| `ROW_NUMBER()` | 为每一行分配一个唯一的序号,即使有相同的值,也会分配不同的序号。 |
| `RANK()` | 为每一行分配一个排名,如果有相同的值,则会共享相同的排名,并跳过后续的序号。 |
二、主要区别
| 特性 | `ROW_NUMBER()` | `RANK()` |
| 唯一性 | 每一行都有唯一的序号 | 相同值的行具有相同的排名 |
| 重复值处理 | 不考虑重复值,按顺序分配不同序号 | 相同值的行共享同一排名,后续序号跳过 |
| 适用场景 | 需要唯一标识每一行的情况(如分页) | 需要排名且允许并列的情况(如成绩排名) |
| 性能影响 | 通常效率较高,因为不涉及并列处理 | 可能稍慢,因为需要判断并列情况 |
三、示例说明
假设有一个学生表 `students`,包含字段 `name` 和 `score`,数据如下:
| name | score |
| Alice | 90 |
| Bob | 85 |
| Charlie | 90 |
| David | 80 |
使用 `ROW_NUMBER()` 查询:
```sql
SELECT name, score, ROW_NUMBER() OVER (ORDER BY score DESC) AS rn
FROM students;
```
结果:
| name | score | rn |
| Alice | 90 | 1 |
| Charlie | 90 | 2 |
| Bob | 85 | 3 |
| David | 80 | 4 |
使用 `RANK()` 查询:
```sql
SELECT name, score, RANK() OVER (ORDER BY score DESC) AS rk
FROM students;
```
结果:
| name | score | rk |
| Alice | 90 | 1 |
| Charlie | 90 | 1 |
| Bob | 85 | 3 |
| David | 80 | 4 |
四、总结
- `ROW_NUMBER()` 更适合需要唯一编号的场景,比如分页或去重。
- `RANK()` 更适合需要排名且允许并列的场景,比如竞赛成绩统计。
- 选择哪个函数取决于业务需求和对“并列”是否敏感。
通过合理使用这两个函数,可以更灵活地处理数据排序与排名问题。


