MariaDB 使用派系对字符串值进行排序
MariaDB sort string value with faction
我有如下 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 查询按内核版本排序?
MariaDB 在 10.7 中试用成功 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)
ref: 有 natural_sort_order
这样怎么样:
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()
从子查询开始使用。这个想法是将一些部分与我认为“可订购”的价值分开。上面的查询将 return 以下内容:
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
我有如下 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 查询按内核版本排序?
MariaDB 在 10.7 中试用成功 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)
ref: 有 natural_sort_order
这样怎么样:
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()
从子查询开始使用。这个想法是将一些部分与我认为“可订购”的价值分开。上面的查询将 return 以下内容:
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 |