Mysql编程实战三之排序问题
2023-09-14 09:13:14 时间
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)
最终排序成功。
相关文章
- Error connecting to database [Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13)]
- Mysql授权允许远程访问解决Navicat for MySQL连接mysql提示客户端不支持服务器请求的身份验证协议;考虑升级MySQL客户端
- 【Mysql安装】Mac下安装mysql
- MySQL按照汉字的拼音排序,mysql汉字排序
- 连接Mysql提示Can’t connect to local MySQL server through socket的解决方法
- MySql修改数据库编码为UTF8
- Ruby on Rails 3 Can't connect to local MySQL server through socket '/tmp/mysql.sock' on linux
- 远程连接Mysql数据库问题(ERROR 2003 (HY000))
- MySQL常见命令 [转]
- 【原创】MySQL Proxy - connect_server()
- 在不升级 mysql 的情况下直接使用 mysql utf8 存储 超过三个字节的 emoji 表情
- PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)--续
- Starting MySQL. ERROR! The server quit without updating PID file (/data/mysql/mysql.pid).
- [转]2006 MySQL server has gone away错误,最大值溢出解决办法 mysql max_allowed_packet 查询和修改
- 实战解析丨如何对Mysql连接请求的tcpdump内容进行分析
- Python编程:prettytable打印出类似MySQL的效果
- 上Mysql com.mysql.jdbc.StatementImpl$CancelTask内存泄漏问题和解决方法
- java mysql驱动
- Linux MySQl 5.7.17 MySQL ERROR 1366(HY000):Incorrect string value 解决方法
- 安全测试===Mysql 注入技巧学习 MySQL注入技巧(1)
- QT连接MySql
- 使用Java JdbcTemplate对mySQL进行CRUD增删改查操作
- 【异常】MySQL提示MysqlDataTruncation: Data truncation: Data too long for column ‘name‘ at row 1
- 【高可用MySQL解决方案】centos7配置mysql主从复制
- 我敢打赌!这道关于MySQL中update加锁的问题,大部分人都答不出来
- MySQL报错Column count of mysql.user is wrong. Expected 43, found 42. Created with MySQL 50568, now run
- MySQL错误:Access denied for user ‘root‘@‘%‘ to database ‘dbname‘