1、业务背景

版本检查接口返回版本号排序时出现如下图所示问题

普通的查询按数字值逐级比较,导致版本号高的排在了后面,这样版本检查根据版本号排序倒排取出来的不是最新的版本号,本文就此问题查询了诸多方法,在此做个总结。

本文线上测试地址为:SQL Fiddle

本文用到的SQL函数的具体说明:MySQL 常用函数一览_SunshineGGB的博客-CSDN博客

模拟测试的表字段和数据如下

create table AppVersion
( VersionNumber varchar(25)); insert into AppVersion (VersionNumber) values
('1.1.0'),
('2.0.34'),
('2.0.38'),
('2.1.0'),
('3.5.6'),
('3.5.8'),
('3.5.13');

2、具体方法

正常查询版本号并按版本号倒序

SELECT VersionNumber
FROM AppVersion
ORDER BY VersionNumber DESC

结果如本文首图所示,会出现3.5.13排在3.5.8和3.5.6下方

1)方法一

通过使用CONCAT添加'0.0.0'来确保每一行至少有4个部分拼接成IP地址的形式,然后使用利用IP处理函数INET_ATON()返回一个代表该地址数值的整数进行排序即可。

【前提】:如果你知道版本号总是有3个分量,并且每个分量总是小于256,那么你可以使用以下方法

执行代码:

SELECT VersionNumber
FROM AppVersion
ORDER BY INET_ATON(CONCAT(VersionNumber, '.0')) DESC

效果如图:

本例代码测试链接地址:SQL Fiddle

2)方法二

同样是利用IP地址函数INET_ATON()和字符串拼接函数CONCAT()。同时使用SUBSTRING_INDEX来拉出前4个部分,使每一个部分看起来像一个IP,然后通过IP处理函数INET_ATON()返回对应的整数值进行比较排序。

执行代码:

SELECT VersionNumber
FROM AppVersion
ORDER BY INET_ATON(SUBSTRING_INDEX(CONCAT(VersionNumber, '.0.0.0'), '.', 4)) DESC

效果如图:

本例代码测试链接地址:SQL Fiddle

3)方法三

获取版本范围:取每组版本号并向前补0至N位(比如5位、10位,下方代码为10位),最后拼接好再进行比较

执行代码:

SELECT VersionNumber
FROM AppVersion
ORDER BY CONCAT(
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 1), '.', -
1), 10, '0'),
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 2), '.', -
1), 10, '0'),
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 3), '.', -
1), 10, '0')
) DESC

效果如图:

本例代码测试链接地址:SQL Fiddle

4)方法四

获取版本顺序:如果只是排序,且版本号都是数字,可以采用每组版本号转数字(下方代码中的*1 、+0皆是转数字的小技巧),再进行排序

执行代码:

SELECT VersionNumber
FROM AppVersion
ORDER BY
SUBSTRING_INDEX(VersionNumber, '.', 1 )*1 DESC,
SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 2 ),'.',-1)*1 DESC,
SUBSTRING_INDEX(VersionNumber, '.', -1 )*1 DESC

效果如图:

本例代码测试链接地址:SQL Fiddle

类似,把*1改成+0一个意思

具体代码:

SELECT VersionNumber
FROM AppVersion
ORDER BY
SUBSTRING_INDEX(VersionNumber, '.', 1 )+0 DESC,
SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 2 ),'.',-1)+0 DESC,
SUBSTRING_INDEX(VersionNumber, '.', -1 )+0 DESC

本例代码测试链接地址:SQL Fiddle

5)方法五

版本号排序:思路是去掉小数点,右边补零防止错误填写,类型转换为数字然后再进行排序

执行代码:

SELECT
VersionNumber,
CONCAT(
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 1), '.', -
1), 3, '0'),
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 2), '.', -
1), 3, '0'),
LPAD(CASE WHEN LENGTH(SUBSTRING_INDEX(VersionNumber, '.', 3)) =
LENGTH(SUBSTRING_INDEX(VersionNumber, '.', 2)) THEN '000'
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(VersionNumber, '.', 3),
'.', -1) END, 3, '0')
) AS VersionNumberSort
FROM
AppVersion
ORDER BY
VersionNumberSort DESC

效果如图:

6)方法六

通过拆分版本号并将每一部分排序为整数和字符串来获得同样的排序结果

执行代码:

SELECT
VersionNumber,
REPLACE(SUBSTRING(SUBSTRING_INDEX(VersionNumber, '.', 1), LENGTH(
SUBSTRING_INDEX(VersionNumber, '.', 1 - 1)) + 1), '.', '') v1,
REPLACE(SUBSTRING(SUBSTRING_INDEX(VersionNumber, '.', 2), LENGTH(
SUBSTRING_INDEX(VersionNumber, '.', 2 - 1)) + 1), '.', '') v2,
REPLACE(SUBSTRING(SUBSTRING_INDEX(VersionNumber, '.', 3), LENGTH(
SUBSTRING_INDEX(VersionNumber, '.', 3 - 1)) + 1), '.', '') v3,
REPLACE(SUBSTRING(SUBSTRING_INDEX(VersionNumber, '.', 4), LENGTH(
SUBSTRING_INDEX(VersionNumber, '.', 4 - 1)) + 1), '.', '') v4
FROM
AppVersion
ORDER BY
0 + v1 DESC, v1 DESC, 0 + v2 DESC, v2 DESC, 0 + v3 DESC, v3 DESC, 0 +
v4 DESC, v4 DESC;

效果如图:

以上就是MySQL 版本号排序的介绍,做此记录,如有帮助,欢迎点赞关注收藏!

MySQL 版本号排序的更多相关文章

  1. 【MySQL】排序原理与案例分析

    前言 排序是数据库中的一个基本功能,MySQL也不例外.用户通过Order by语句即能达到将指定的结果集排序的目的,其实不仅仅是Order by语句,Group by语句,Distinct语句都会隐 ...

  2. mysql 自定义排序顺序

    mysql 自定义排序顺序 实例如:在sql语句中加入ORDER BY FIELD(status,3,4,0,2,1)语句可定义排序顺序 SELECT tsdvoucher0_.VOUCHER_ID ...

  3. CentOS6.x升级MySQL版本号5.1到5.6

    有一些虚拟机.云主机提供商仍然使用的是老版本号的安装套件. 预装的应用软件版本号非常低. 比方 techbrood.com 使用的云server,当中MySQL预装版本号为老版本号5.1.x. 而最新 ...

  4. Mysql 版本号、存储引擎、索引查询

    [1]Mysql 版本号.存储引擎.索引查询 # 查看数据库版本号 SELECT VERSION(); # 查看数据库支持的引擎(默认即Support == DEFAULT行) SHOW ENGINE ...

  5. SQL Server 与MySQL中排序规则与字符集相关知识的一点总结

    字符集&&排序规则 字符集是针对不同语言的字符编码的集合,比如UTF-8字符集,GBK字符集,GB2312字符集等等,不同的字符集使用不同的规则给字符进行编码排序规则则是在特定字符集的 ...

  6. MySQL分组排序(取第一或最后)

    MySQL分组排序(取第一或最后) 方法一:速度非常慢,跑了30分钟 SELECT custid, apply_date, rejectrule FROM ( SELECT *, IF ( , ) A ...

  7. MySQL的排序(order by)

    MySQL的排序(order by) 1.降序(DESC) 2.升序(ASC) 1. 降序(DESC) 完整代码: SELECT `学号`,`考试日期`,`考试成绩` FROM `表2`ORDER B ...

  8. list中的对象或者map中的版本号排序 version排序

    经常会用到版本号排序,直接把他封装成一个工具用起来比较方便. List<A> aList = new ArrayList<>(); ...aList 赋值 ... Collec ...

  9. mysql order排序

    使用order by  可以对结果进行排序, 默认情况下,order by 以升序进行排序,因此ASC 子句是可选的. DESC 是降序排列. 升序 select * from emp where d ...

  10. mysql高级排序&高级匹配查询示例

    在大多数应用场景下,我们使用mysql进行查询时只会用到'=', '>' , '<' , in, like 等常用的方法,看起来,大多数情况下,已经足以应付我们的小型应用了.不过,在一些特 ...

随机推荐

  1. windows server2016/2019在vmware上安装失败

    问题:无法进入装机界面 现象一:打开虚拟机后进入虚拟bios界面,无法引导iso镜像 解决方法1:从虚拟机设置里,修改引导选项,如果需要修改启动盘则设置强制执行BIOS设置 下图为vsphere的截图 ...

  2. Atcoder补题计划

    11.17 AtCoder Regular Contest 151 知识点: A:简单题 B:计数,并查集 补题传送门

  3. VS 新版本无法打开旧项目问题处理

    问题 最近想阅读 WorkflowCore 的源码,苦于代码量巨大,就想将项目回退到 Init Commit 版本 但是在回退版本后,工程内Project 显示已卸载 重新加载后 提示: 不支持 Th ...

  4. volatile关键字在并发中有哪些作用?

    作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA源码.职业成长.项目实战.面试相关资料等更多精彩文章在公众号「小牛呼噜噜」 前言 读过笔者之前的一篇文章J ...

  5. 【JVM调优】Day01:Garbage的概念、垃圾回收的算法(标记清除、拷贝、标记压缩)、各种垃圾回收器(Serial、Parallel、CMS并发)及存在的问题

    〇.前言 简历写上:熟悉GC常用算法,熟悉常见垃圾回收器.具有实际JVM调优实战经验 瞬间涨3k 一.什么是garbage Java中垃圾回收器自动进行垃圾回收,不用自己回收 new 对象在内存中,c ...

  6. Windows10下python3和python2同时安装(三)VS 2013配置python环境

    Windows10下python3和python2同时安装(三) VS 2013配置python环境 说明:本文基于python2和python3同时安装之后,对VS 2013进行配置,下面有些地方文 ...

  7. 深入理解 MySQL 的事务隔离级别和 MVCC 机制

    前言 我们都知道 MySQL 实现了 SQL 标准中的四个隔离级别,但是具体是如何实现的可能还一知半解,本篇博客将会从代码层面讲解隔离级别的实现方式,下面进入正题. 事务 考虑这样一个场景:博主向硝子 ...

  8. Django聚合函数与分组查询

    目录 一:聚合查询 1.聚合函数作用 2.聚合函数查询关键字: 3.聚合函数 4.聚合函数使用 二:分组查询 1.分组查询 2.返回值 3.分组查询关键字 4.分组查询特点 5总结: 三:分组使用 1 ...

  9. PhaApi NOTORM 实现分表分库

    通过自增ID取模要分表的数量,便可得到表名.例如log表分成100张表:log_1,log2...,log100. 每次数据库CURD都先通过获取ID分配到相对应的表,例如:id=66,取模后的结果是 ...

  10. Jmeter 之跨线程传参

    其他线程使用某个线程中提取的值,比如场景:客户端一直与服务端保持连接的同时进行其他业务操作 1.建立以下两个线程组,并添加相应业务接口 2.发送心跳时,需要token,在用户登录接口下添加提取器提取t ...