【问题标题】:MariaDB sort string value with factionMariaDB排序字符串值与派系
【发布时间】:2022-01-21 02:30:45
【问题描述】:

我有像下面这样的 Linux 内核版本,想把这个值从内核版本最旧到最新排序。

4.18.0-348.7.1.el8_5.x86_64
4.18.0-358.el8.x86_64
4.18.0-305.19.1.el8_4.x86_64
4.18.0-348.12.2.el8_5.x86_64
4.18.0-348.7.1.el8_5.x86_64

使用此查询,它不按内核版本排序。我希望这一行 4.18.0-348.12.2.el8_5.x86_64 应该在最后一行之上。

select kernel, REGEXP_REPLACE(kernel,'\\.|-|el.*$','') as k from os  group by kernel order by 1;

4.18.0-305.19.1.el8_4.x86_64,4180305191
4.18.0-338.el8.x86_64,4180338
4.18.0-348.12.2.el8_5.x86_64,4180348122
4.18.0-348.2.1.el8_5.x86_64,418034821
4.18.0-348.7.1.el8_5.x86_64,418034871
4.18.0-358.el8.x86_64,4180358

如何让这个sql查询按内核版本排序?

【问题讨论】:

  • 4.18.0-348.2.1 之前你对4.18.0-348.12.2 有什么期望?
  • @TimBiegeleisen 4.18.0-348.12.21 应该在 4.18.0-348.2.1 之后

标签: mysql mariadb


【解决方案1】:

10.7 中的 MariaDB 已成功试用 natural_sort_order,即将发布 GA:

MariaDB [test]> create table v( version varchar(30));
Query OK, 0 rows affected (0.002 sec)

MariaDB [test]> insert into v values ('4.18.0-348.7.1.el8_5.x86_64'),('4.18.0-358.el8.x86_64'),('4.18.0-305.19.1.el8_4.x86_64'),('4.18.0-348.12.2.el8_5.x86_64'),('4.18.0-348.7.1.el8_5.x86_64');

MariaDB [test]> select version from v order by natural_sort_key(version);
+------------------------------+
| version                      |
+------------------------------+
| 4.18.0-305.19.1.el8_4.x86_64 |
| 4.18.0-348.7.1.el8_5.x86_64  |
| 4.18.0-348.7.1.el8_5.x86_64  |
| 4.18.0-348.12.2.el8_5.x86_64 |
| 4.18.0-358.el8.x86_64        |
+------------------------------+
5 rows in set (0.001 sec)

参考:有natural_sort_order

【讨论】:

  • 很高兴知道,我的 MriaDB 版本是 10.5。
【解决方案2】:

这样怎么样:

SELECT kernel,
       k1, k2, k3,
       CASE WHEN k3 LIKE '%-%' THEN 0
        ELSE SUBSTRING_INDEX(k3,'.',1)+0 END AS k4,
       CASE WHEN k3 LIKE '%-%' THEN 0
        ELSE SUBSTRING_INDEX(k3,'.',-1) END AS k5
FROM       
(SELECT kernel,
       SUBSTRING_INDEX(kernel,'-',1) AS k1,
       SUBSTRING_INDEX(SUBSTRING_INDEX(kernel,'-',-1),'.',1) AS k2,
       SUBSTRING_INDEX(SUBSTRING_INDEX(kernel,'.el',1),'.',-2) AS k3
 FROM
    os) V
ORDER BY 
  k1, k2, k4, k5
;

从子查询开始使用一堆SUBSTRING_INDEX()。这个想法是将一些部分与我认为“可订购”的值分开。上面的查询将返回以下内容:

kernel k1 k2 k3 k4 k5
4.18.0-305.19.1.el8_4.x86_64 4.18.0 305 19.1 19 1
4.18.0-338.el8.x86_64 4.18.0 338 18.0-338 0 0
4.18.0-348.2.1.el8_5.x86_64 4.18.0 348 2.1 2 1
4.18.0-348.7.1.el8_5.x86_64 4.18.0 348 7.1 7 1
4.18.0-348.12.2.el8_5.x86_64 4.18.0 348 12.2 12 2
4.18.0-358.el8.x86_64 4.18.0 358 18.0-358 0 0

Demo

【讨论】:

    猜你喜欢
    • 2018-02-06
    • 2016-03-05
    • 1970-01-01
    • 2013-04-19
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多