如何在SQL查询中生成按Id分组的Sequenceno序号?
嘿,这个需求挺常见的,你可以通过窗口函数或者用户变量(针对旧版数据库)来生成想要的Sequenceno列,不同数据库的写法略有区别,我给你整理几种常用方案:
1. 支持窗口函数的数据库(SQL Server、MySQL 8.0+、PostgreSQL、Oracle 12c+等)
这是最简洁的实现方式,用ROW_NUMBER()窗口函数按Id分组,再按Desc列排序生成连续序号:
SELECT Id, `Desc`, -- 注意:Desc是很多数据库的关键字,需要用反引号/双引号包裹 ROW_NUMBER() OVER (PARTITION BY Id ORDER BY `Desc`) AS Sequenceno FROM YourTableName;
简单解释下:
PARTITION BY Id:把数据按Id分成不同的组ORDER BYDesc``:在每个组内按Desc列的顺序排列ROW_NUMBER():给每个组内的行分配从1开始的连续序号,正好匹配你示例里的效果
2. MySQL 5.x及更早版本(不支持窗口函数)
如果你的MySQL版本比较旧,没法用窗口函数,可以用用户变量来模拟序号生成:
SELECT Id, `Desc`, @row_num := CASE WHEN @prev_id = Id THEN @row_num + 1 ELSE 1 END AS Sequenceno, @prev_id := Id FROM YourTableName, (SELECT @row_num := 0, @prev_id := NULL) AS vars ORDER BY Id, `Desc`;
这里的逻辑是:
- 用
@row_num记录当前序号,@prev_id记录上一行的Id - 每一行判断:如果当前
Id和上一行相同,序号加1;否则重置为1 - 最后一定要按
Id和Desc排序,确保序号生成的顺序正确
小提示
- 记得把
YourTableName替换成你实际使用的表名 - 如果
Desc不是关键字(或者你的数据库允许),可以去掉反引号;但为了避免语法错误,建议加上 - 如果你遇到
Desc有重复值的场景,且希望相同值的序号一致,可以换成RANK()或DENSE_RANK(),不过从你的示例来看,ROW_NUMBER()完全够用
内容的提问来源于stack exchange,提问作者Sagar padhiyar
相关产品推荐
相关产品推荐

