今天在群里看到了这样的一个需求,如下图所示,将图中左边的数据转变成右边的结果。
咋一看,不就是先按姓名做排序,然后再分别对班组、机台号做排序么。按这个思路写出了 SQL(表结构及数据在文末),得到的结果和预期的有点不一样。
SELECT
*
FROM
weird_order
ORDER BY 姓名,
班组,
机台号
上面的 SQL 执行的结果 >>
机台号 姓名 班组
------ ------ --------
1 张三 1
2 张三 1
3 张三 1
1 李四 2
2 李四 2
3 李四 2
4 王五 1
5 王五 1
6 王五 1
7 赖八 2
8 赖八 2
9 赖八 2
4 赵柳 2
5 赵柳 2
6 赵柳 2
7 麻七 1
8 麻七 1
9 麻七 1
原来中文字段自有它的排序规则,只对姓名执行 ORDER BY
可以把同姓名的数据排在一起,却不能让不同名的人按照其在数据里出现的顺序排序。
上图中右边数据里的姓名排序是按照左边数据中该姓名出现的顺序决定的,左边最开始出现的姓名是“张三”,其次是“李四”,再接着“王五”、“赵柳”、“麻七”、“赖八”。
因此,我们只要将数据按照姓名出现的顺序给它排序,然后对序号排序而不是姓名排序即可实现需求。
按姓名出现的顺序分配的排序序号的 SQL 可以这么写:
SELECT
姓名,
MIN(原始序号) AS 新序号
FROM
(SELECT
*,
row_number () over () AS '原始序号'
FROM
weird_order) t
GROUP BY 姓名
分配的新序号的结果>>
姓名 新序号
------ --------
张三 1
李四 2
王五 7
赵柳 8
麻七 13
赖八 14
将原表和姓名排序的临时结果关联,按新序号、班组、机台号得到最终结果。
SELECT
t.机台号,
t.姓名,
t.班组
FROM
weird_order t
INNER JOIN
(SELECT
姓名,
MIN(原始序号) AS 新序号
FROM
(SELECT
*,
row_number () over () AS '原始序号'
FROM
weird_order) t
GROUP BY 姓名) tt
ON tt.姓名 = t.姓名
ORDER BY 新序号,
班组,
机台号
表结构及数据
create table weird_order
(
机台号 int,
姓名 char(20),
班组 int
);
INSERT INTO `weird_order` (`机台号`, `姓名`, `班组`)
VALUES
(1, '张三', 1),
(1, '李四', 2),
(2, '张三', 1),
(2, '李四', 2),
(3, '张三', 1),
(3, '李四', 2),
(4, '王五', 1),
(4, '赵柳', 2),
(5, '王五', 1),
(5, '赵柳', 2),
(6, '王五', 1),
(6, '赵柳', 2),
(7, '麻七', 1),
(7, '赖八', 2),
(8, '麻七', 1),
(8, '赖八', 2),
(9, '麻七', 1),
(9, '赖八', 2);
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有