sql server如何输出排序序号_怪异的排序

今天在群里看到了这样的一个需求,如下图所示,将图中左边的数据转变成右边的结果。

462217580f0b7dfc9e233f8bd976f855.png

咋一看,不就是先按姓名做排序,然后再分别对班组、机台号做排序么。按着这个思路写出了 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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值