mysql row_number() over()
时间: 2025-07-22 08:07:38 浏览: 2
MySQL 中的 `ROW_NUMBER()` 是窗口函数的一种,用于为查询结果集中的每一行分配一个唯一的连续序号。该函数从 `1` 开始递增,且不会因为排序字段的值重复而重复编号。`ROW_NUMBER()` 通常与 `OVER()` 子句一起使用,以定义编号的逻辑窗口。
### 使用方法
`ROW_NUMBER()` 的基本语法如下:
```sql
ROW_NUMBER() OVER (
[PARTITION BY partition_expression, ... ]
ORDER BY sort_expression [ASC | DESC], ...
)
```
- `PARTITION BY`:可选,用于将数据划分为多个分区,每个分区独立计算行号。
- `ORDER BY`:必填,用于指定在每个窗口或分区内部的排序规则,从而决定行号的分配顺序。
### 示例代码
#### 示例 1:对整个结果集分配唯一行号
以下示例为整个查询结果集中的每一行分配一个唯一的行号,按 `score` 字段降序排列:
```sql
SELECT id, class, score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM test1;
```
输出结果中,每一行的 `row_num` 列会根据 `score` 从高到低分配一个唯一的序号。
#### 示例 2:按分组分配行号
以下示例按照 `class` 字段进行分组,并在每个分组内按 `score` 降序排列,为每一行分配行号:
```sql
SELECT id, class, score,
ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC) AS row_num
FROM test1;
```
此查询会为每个 `class` 分组内的数据按 `score` 从高到低分配行号,每个分组的行号都从 `1` 开始。
#### 示例 3:MySQL 5.7 中模拟 `ROW_NUMBER() OVER()` 功能
由于 `ROW_NUMBER()` 是 MySQL 8.0 才引入的功能,对于 MySQL 5.7 或更早版本,需要使用变量来模拟实现类似的功能。例如,按 `class` 分组并按 `score` 降序排列:
```sql
SELECT id, class, score,
IF(@pdept = class, @rank := @rank + 1, @rank := 1) AS row_num,
@pdept := class
FROM (
SELECT * FROM test1
ORDER BY class, score DESC
) AS sorted_data
CROSS JOIN (SELECT @rank := 0, @pdept := NULL) AS vars;
```
通过使用用户变量 `@rank` 和 `@pdept`,可以模拟 `ROW_NUMBER()` 的功能,在每个分组内生成递增的行号。
### 注意事项
- `ROW_NUMBER()` 会为每一行生成唯一的序号,即使排序字段的值相同,也不会出现重复的行号。
- 如果希望在相同排序字段值的情况下生成相同的编号,可以考虑使用 `RANK()` 或 `DENSE_RANK()` 窗口函数。
- `ROW_NUMBER()` 通常用于排名、分页、去重等场景,特别是在大数据量的分析中非常有用。
阅读全文
相关推荐


















