在mysql和oracle数据库中按数字排序字符串

8ljdwjyq  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(400)

我有两个数据库列(datatypevarchar),其中包含如下值

column 1 
--------
1.8.0
1.7.0
9.0
10.0

column 2
--------
121
65
78

在ui上,我必须合并这两列并显示如下值

1.8.0_121
1.8.0_78

问题是在对ui上显示的组合列进行排序时。因为这两个列都是varchar,按db order排序,by使用string,121在78之前,这对于升序是错误的。
作为一个解决方案,我在这些列上使用了abs for mysql和to\u number for oracle。mysql在这两个列上都运行良好,但是oracle to\ u number在第一个列上抛出错误“invalid number”,因为它的值为1.8.0
请建议如何处理这种情况只使用代码更改。因为数据库模式的改变会导致许多系统发生大量的改变,所以我不想碰这个。

带数据的示例表


带order by子句的查询

SELECT (MAJOR || '_' || MINOR) AS VER 
FROM VERSION 
ORDER BY MAJOR ASC, MINOR ASC

结果

更正了将varchar列视为数字的查询

SELECT (MAJOR || '_' || MINOR) AS VER 
FROM VERSION 
ORDER BY MAJOR ASC, TO_NUMBER(MINOR) ASC

修正结果


直到现在一切都很好。但问题是主列可以有9.0和10.0这样的值,所以我想将主列也转换为ORDERBY子句中的\u数字,这样排序是正确的。但由于值是1.8.0,因此抛出错误。
有争议的案件是

dw1jzc5e

dw1jzc5e1#

这个查询对我有用。

SELECT ( major 
     || '_' 
     || minor ) AS ver 
FROM   
(SELECT major, minor, 
    To_number(Replace(Decode(Substr(major, 0, 2), '1.',Substr(major, 3), major), '.', '')) 
      AS major_num, 
    To_number(Decode(Instr(minor, '-'), 0, minor,Substr(minor, 0, Instr(minor, '-') - 1))) 
      AS minor_num 
FROM   version) 
ORDER  BY major_num, 
      minor_num;
oyjwcjzk

oyjwcjzk2#

一种选择是提取所有数字片段(使用正则表达式;我认为这是最简单的选择 TO_NUMBER 并按这些值排序,例如。

SQL> with test (col) as
  2    (select '1.8.0' from dual union
  3     select '1.7.0' from dual union
  4     select '9.0'   from dual union
  5     select '10.0'  from dual
  6    )
  7  select col
  8  from test
  9  order by to_number(regexp_substr(col, '\d+', 1, 1)),
 10           to_number(regexp_substr(col, '\d+', 1, 2)),
 11           to_number(regexp_substr(col, '\d+', 1, 3));

COL
-----
1.7.0
1.8.0
9.0
10.0

SQL>
wj8zmpe1

wj8zmpe13#

这里有一个黑客。。。

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(column1 VARCHAR(12) NOT NULL
,column2 DECIMAL(5,2) NULL
);

INSERT INTO my_table VALUES
('1.8.0',121),
('1.7.0',65),
('9.0',78),
('10.0',NULL);

SELECT a.column1
     , b.column2 
  FROM 
     (SELECT column1,@i:=@i+1 i FROM my_table,(SELECT @i:=0) vars ORDER BY INET_ATON(column1))a
  JOIN
     (SELECT column2,@j:=@j+1 j FROM my_table,(SELECT @j:=0) vars ORDER BY ISNULL(column2),column2)b
    ON b.j = a.i;
+---------+---------+
| column1 | column2 |
+---------+---------+
| 1.7.0   |   65.00 |
| 1.8.0   |   78.00 |
| 9.0     |  121.00 |
| 10.0    |    NULL |
+---------+---------+

相关问题