
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。而MySQL5.7中由于没有这类函数,该如何实现呢,下面对比MySQL8.0,列举两种情况的实现。
1. 数据准备
创建一张演示表
#创建表
CREATE TABLE users (
id INT PRIMARY KEY,
group_id INT,
c_name VARCHAR(64)
);
复制
插入演示数据
-- 插入10行数据
INSERT INTO users VALUES (1, 1, '张三');
INSERT INTO users VALUES (2, 1, '李四');
INSERT INTO users VALUES (3, 2, '王五');
INSERT INTO users VALUES (4, 2, '赵六');
INSERT INTO users VALUES (5, 3, '钱七');
INSERT INTO users VALUES (6, 1, '周八');
INSERT INTO users VALUES (7, 2, '吴九');
INSERT INTO users VALUES (8, 3, '郑十');
INSERT INTO users VALUES (9, 1, '孙十一');
INSERT INTO users VALUES (10, 3, '李十二');
复制
2. 生成序号
2.1 使用窗口函数ROW_NUMBER()实现
在MySQL8.0中可以直接使用窗口函数ROW_NUMBER()来实现序号的生成,例如
# 根据c_name字段进行排序生成序号
SELECT
ROW_NUMBER() OVER (ORDER BY c_name) AS row_num,
id,
c_name
FROM
users;
复制
结果如下:
+---------+----+-----------+
| row_num | id | c_name |
+---------+----+-----------+
| 1 | 7 | 吴九 |
| 2 | 6 | 周八 |
| 3 | 9 | 孙十一 |
| 4 | 1 | 张三 |
| 5 | 10 | 李十二 |
| 6 | 2 | 李四 |
| 7 | 3 | 王五 |
| 8 | 4 | 赵六 |
| 9 | 8 | 郑十 |
| 10 | 5 | 钱七 |
+---------+----+-----------+
10 rows in set, 1 warning (0.00 sec)
复制
2.2 低版本MySQL中的实现
因为在MySQL8.0版本之前无ROW_NUMBER()窗口函数,因此需要结束变量来实现。具体示例如下:
SET @row_num = 0;
SELECT
(@row_num:=@row_num + 1) AS row_num,
id,
c_name
FROM
users
ORDER BY
c_name;
复制
结果如下:
+---------+----+-----------+
| row_num | id | c_name |
+---------+----+-----------+
| 1 | 7 | 吴九 |
| 2 | 6 | 周八 |
| 3 | 9 | 孙十一 |
| 4 | 1 | 张三 |
| 5 | 10 | 李十二 |
| 6 | 2 | 李四 |
| 7 | 3 | 王五 |
| 8 | 4 | 赵六 |
| 9 | 8 | 郑十 |
| 10 | 5 | 钱七 |
+---------+----+-----------+
10 rows in set, 1 warning (0.00 sec)
复制
注意:每次执行前需要将@row_num重新设置为0 ,即执行SET @row_num = 0;
3. 分组后排序
3.1 继续使用窗口函数ROW_NUMBER()实现
在MySQL8.0中可以继续使用窗口函数ROW_NUMBER()来实现分组排序的功能,例如:
SELECT
id,
group_id,
c_name,
ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY id) AS row_num
FROM
users
ORDER BY
group_id, id;
复制
运行结果如下:
+----+----------+-----------+---------+
| id | group_id | c_name | row_num |
+----+----------+-----------+---------+
| 1 | 1 | 张三 | 1 |
| 2 | 1 | 李四 | 2 |
| 6 | 1 | 周八 | 3 |
| 9 | 1 | 孙十一 | 4 |
| 3 | 2 | 王五 | 1 |
| 4 | 2 | 赵六 | 2 |
| 7 | 2 | 吴九 | 3 |
| 5 | 3 | 钱七 | 1 |
| 8 | 3 | 郑十 | 2 |
| 10 | 3 | 李十二 | 3 |
+----+----------+-----------+---------+
10 rows in set (0.00 sec)
复制
3.2 低版本MySQL中的实现
因为涉及到分组及分组后排序,因此需要引入2个变量,一个用于分组标识,一个用于组内排序标识,示例如下:
SET @row_num = 0;
SET @g_id = NULL;
SELECT
id,
group_id,
c_name,
@row_num := CASE
WHEN @g_id = group_id THEN @row_num + 1
ELSE 1
END AS row_num,
@g_id := group_id AS v_gid
FROM
users
ORDER BY
group_id, id;
复制
运行结果如下:
+----+----------+-----------+---------+-------+
| id | group_id | c_name | row_num | v_gid |
+----+----------+-----------+---------+-------+
| 1 | 1 | 张三 | 1 | 1 |
| 2 | 1 | 李四 | 2 | 1 |
| 6 | 1 | 周八 | 3 | 1 |
| 9 | 1 | 孙十一 | 4 | 1 |
| 3 | 2 | 王五 | 1 | 2 |
| 4 | 2 | 赵六 | 2 | 2 |
| 7 | 2 | 吴九 | 3 | 2 |
| 5 | 3 | 钱七 | 1 | 3 |
| 8 | 3 | 郑十 | 2 | 3 |
| 10 | 3 | 李十二 | 3 | 3 |
+----+----------+-----------+---------+-------+
10 rows in set, 2 warnings (0.00 sec)
复制
这样就实现了分组及排序的序号生成。

2. mysql8.0新增用户及加密规则修改的那些事
3. 比hive快10倍的大数据查询利器-- presto
4. 监控利器出鞘:Prometheus+Grafana监控MySQL、Redis数据库
5. PostgreSQL主从复制--物理复制
6. MySQL传统点位复制在线转为GTID模式复制




文章转载自数据库干货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1296次阅读
2025-03-13 11:40:53
MySQL8.0统计信息总结
闫建(Rock Yan)
487次阅读
2025-03-17 16:04:03
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
458次阅读
2025-03-13 14:38:19
Ogg23ai高手必看-MySQL Innodb Cluster跟oracle的亲密接触
曹海峰
455次阅读
2025-03-04 21:56:13
SQL优化 - explain查看SQL执行计划(一)
金同学
390次阅读
2025-03-13 16:04:22
MySQL突然崩溃?教你用gdb解剖core文件,快速锁定“元凶”!
szrsu
349次阅读
2025-03-13 00:29:43
MySQL生产实战优化(利用Index skip scan优化性能提升257倍)
chengang
327次阅读
2025-03-17 10:36:40
金仓数据库26套!宁波市司法局信息系统适配改造(一期)采购项目
天下观查
321次阅读
2025-03-21 10:33:59
达梦数据与法本信息签署战略合作协议
达梦数据
296次阅读
2025-03-06 09:26:57
国产化+性能王炸!这套国产方案让 3.5T 数据 5 小时“无感搬家”
YMatrix
279次阅读
2025-03-13 09:51:26