mysql - Oracle/MYSQL : Sort records from a select query on a column that contains alphanumeric values

标签 mysql sql oracle sorting

我知道这个问题已经以各种形式提出,但我的要求恰好有点不同。

假设我有一个包含如下数据的表:

ID  NAME        VALUE

-----------------------------

1   ABC-2-2     X
2   PQRS-1-3    Y
3   ABC-3-2     Z
4   PQRS-1-4    A
5   PQRS-3-4    B
6   MNO-2-1     C
7   AAA-1       D
8   BBB-2       E
9   CCC-3       F

现在,我期望的输出应该如下所示:

ID  NAME        VALUE

-----------------------------
7   AAA-1       D
2   PQRS-1-3    Y
4   PQRS-1-4    A
8   BBB-2       E
6   MNO-2-1     C
1   ABC-2-2     X
9   CCC-3       F
3   ABC-3-2     Z
5   PQRS-3-4    B

请注意,这不是直接的字母数字排序。相反,第一个“-”之前的值将被忽略,并且字段将根据名称中第一个“-”之后的内容进行排序。

我对 PL/SQL 不太熟悉,如果您能提供任何形式的帮助,我们将不胜感激。

谢谢。

PS:请注意,这应该适用于 Oracle 和 MySQL。

最佳答案

对于您的示例来说,这就足够了(Oracle 语法):

ORDER BY SUBSTR(name,4)

如果第一个连字符之前的字符数可能不同,您可以这样做(同样是 Oracle 语法):

ORDER BY SUBSTR(name,INSTR(name,'-')+1)

但是,如果您的代码如下:

AAA-10-1
AAA-8-1
AAA-9-1

并预计 AAA-10-1 出现在 AAA-9-1 之后。然后你需要进一步解析它:

ORDER BY LPAD(SUBSTR(name,INSTR(name,'-')+1, INSTR(name,'-',1,2)-INSTR(name,'-')-1),10,'0'),
         LPAD(SUBSTR(name,INSTR(name,'-',1,2)+1),10,'0')

(注意,我使用 LPAD(x,10,'0') 将“1”等值转换为“0000000001”等,而不是使用 TO_NUMBER,因为如果其中有任何非数字,这可能会失败您的数据。)

示例:

with data as
(
select 'AAA-1' name from dual
union all
select 'PQR-1-4' name from dual
union all
select 'PQR-1-3' name from dual
union all
select 'AAA-10-10' name from dual
union all
select 'AAA-10-1' name from dual
union all
select 'AAA-9-10' name from dual
union all
select 'AAA-9-1' name from dual
)
select *
from data
ORDER BY LPAD(SUBSTR(name,INSTR(name,'-')+1, INSTR(name,'-',1,2)-INSTR(name,'-')-1),10,'0'),
         LPAD(SUBSTR(name,INSTR(name,'-',1,2)+1),10,'0');

输出:

NAME
---------
PQR-1-3
PQR-1-4
AAA-9-1
AAA-9-10
AAA-10-1
AAA-10-10
AAA-1

如果 AAA-1 应该先出现:

ORDER BY LPAD(SUBSTR(name,INSTR(name,'-')+1, INSTR(name||'-','-',1,2)-INSTR(name,'-')-1),10,'0'),
         LPAD(SUBSTR(name,INSTR(name||'-','-',1,2)+1),10,'0') nulls first

关于mysql - Oracle/MYSQL : Sort records from a select query on a column that contains alphanumeric values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14363209/

相关文章:

mysql - 在mariadb中查询数据时如何包含两个SET语句

mysql - MySQL 中的多选查询

sql - PostgreSQL - 从条件聚合结果中删除 NULLS 行和列

sql - 确定连续的日期间隔

MySQL通过将不同表中的单元格相乘得到结果

java - 将 PROPAGATION_REQUIRED_NEW 与两个单独的 spring bean 一起使用时的 Oracle 数据库锁定

mysql - SQL:选择 child 及其 child 的数量

mysql:在同一列中比较后更改值

windows - 从命令行安装 Oracle Client,无需用户交互

sql - Oracle - 从表中选择 n-1 条记录