0
点赞
收藏
分享

微信扫一扫

Mysql编程实战三之排序问题

文风起武 2022-01-28 阅读 40


Mysql编程实战三之排序问题

1.需求

使用SQL语句将表中的数据排序。分别有两种排序规则,一种是全局增序一种相同名次同序但全局增序

2.表数据

  • 建表语句如下:
CREATE TABLE `t` (
`a` char(1) DEFAULT NULL
) ENGINE=InnoDB
  • 插入数据
INSERT INTO insidemysql.t (a) 
VALUES
('x'),
('x'),
('x'),
('y'),
('y'),
('z');

3.实现代码

  • 全局增序:按照字母顺序排名,但是相同排名依然增序,比如现在有一组字母,排序结果应该如下:
+------+------+
| chara| rank |
+------+------+
| x | 1 |
| x | 2 |
| x | 3 |
| y | 4 |
| y | 5 |
| z | 6 |
+------+------+
select 
a
,(
select
count(*)
from t t_2
where t_1.a >= t_2.a
)as rank
from t t_1;
+------+------+
| a | rank |
+------+------+
| x | 3 |
| x | 3 |
| x | 3 |
| y | 5 |
| y | 5 |
| z | 6 |
+------+------+
6 rows in set (0.00 sec)

可以看到,排序结果并非我们想要的

  • 再次修改代码如下
select
a
,case when @field = a
then @rank
else @rank := @rank + 1 end as rank
,@field := a
from
(
select
a
from t
) as t_1,
(
select
@rank := 0,
@field := null
)as t_2

+------+------+-------------+
| a | rank | @field := a |
+------+------+-------------+
| x | 1 | x |
| x | 1 | x |
| x | 1 | x |
| y | 2 | y |
| y | 2 | y |
| z | 3 | z |
+------+------+-------------+
6 rows in set (0.00 sec)

还不是想要的结果

select
a
,@rank := @rank + 1 as rank
from
(
select
a
from t
) as t_1,
(
select
@rank := 0,
@field := null
)as t_2
+------+------+
| a | rank |
+------+------+
| x | 1 |
| x | 2 |
| x | 3 |
| y | 4 |
| y | 5 |
| z | 6 |
+------+------+
6 rows in set (0.00 sec)

这么来看,这个SQL像是解决了问题,但是真的是这样么?插入两条数据:

insert into t select 'a';
insert into t select 'z';

再次执行这个语句,结果发现出了问题:

+------+------+
| a | rank |
+------+------+
| x | 1 |
| x | 2 |
| x | 3 |
| y | 4 |
| y | 5 |
| z | 6 |
| a | 7 |
| z | 8 |
+------+------+

这里没有把​​a​​​,​​z​​​按照字母顺序存储,即没有排序,使用​​order by​​的SQL如下:

select
a
,@rank := @rank + 1 as rank
from
(
select
a
from t
order by a
) as t_1,
(
select
@rank := 0,
@field := null
)as t_2;
+------+------+
| a | rank |
+------+------+
| a | 1 |
| x | 2 |
| x | 3 |
| x | 4 |
| y | 5 |
| y | 6 |
| z | 7 |
| z | 8 |
+------+------+
8 rows in set (0.00 sec)

从结果看,没有问题。但是接着问题又来了,现在的需求是:

  • 2.相同名次同序但全局增序:按照字母顺序排名,但是相同的字母有着相同的排名,比如说,现在有一组字符,他们的排序结果应该如下:
+------+------+
| chara| rank |
+------+------+
| x | 1 |
| x | 1 |
| x | 1 |
| y | 4 |
| y | 4 |
| z | 6 |
+------+------+
select
a
,case when @field != a
then @rank := @rank + 1
else @rank
end as rank

,@field := a
from
(
select
a
from t
order by a
) as t_1,
(
select
@rank := 0,
@field := null
)as t_2;

执行结果如下:

+------+------+-------------+
| a | rank | @field := a |
+------+------+-------------+
| a | 0 | a |
| x | 1 | x |
| x | 1 | x |
| x | 1 | x |
| y | 2 | y |
| y | 2 | y |
| z | 3 | z |
| z | 3 | z |
+------+------+-------------+
8 rows in set (0.00 sec)

这个SQL实现了相同字母相同排序的功能,但是没有实现全局增量排序,修改SQL如下:

select
a
,case when @field = a
then @rank := @rank
else @rank := @ord end as rank
,@field := a
,@ord := @ord +1
from
(
select
a
from t
order by a
) as t_1,
(
select
@rank := 1,
@ord := 1,
@field := null
)as t_2;
+------+------+-------------+-----------------+
| a | rank | @field := a | @ord := @ord +1 |
+------+------+-------------+-----------------+
| a | 1 | a | 2 |
| x | 2 | x | 3 |
| x | 2 | x | 4 |
| x | 2 | x | 5 |
| y | 5 | y | 6 |
| y | 5 | y | 7 |
| z | 7 | z | 8 |
| z | 7 | z | 9 |
+------+------+-------------+-----------------+
8 rows in set (0.00 sec)

最终排序成功。



举报

相关推荐

0 条评论