列的最大值

Maximum value of a column

在我的 Oracle 数据库中,我在一列中有这些值:

6.40.123580

10.10.114580

10.10.114582

我想在此列上执行 MAX() 函数,但如果以我的示例为例,我永远不会得到“10.10.114582”。它显示“6.40.123580”。

有解决办法吗? 谢谢!

直接在字符串上使用 MAX 不起作用,因为它将值作为字符串进行比较并查找最大的第一个字符,然后是最大的第二个字符,等等。因为 6(在开始时6.40.123580) 大于 1(在 10.10.11458? 的开头),那么 6.40.123580 作为字符串比较时更大。

您需要做的是在 . 字符处拆分字符串,然后比较各个部分的数值。


为此,您可以使用简单(快速)字符串函数找到 . 分隔符的位置,然后找到这些分隔符之间的 sub-strings 以获得数字组件,然后取每个连续分量中具有最大值的行:

SELECT version_number,
       TO_NUMBER(SUBSTR(version_number,        1, sep1 -    1)) AS major,
       TO_NUMBER(SUBSTR(version_number, sep1 + 1, sep2 - sep1)) AS minor,
       TO_NUMBER(SUBSTR(version_number, sep2 + 1)) AS patch
FROM   (
  SELECT version_number,
         INSTR(version_number,'.',1,1) AS sep1,
         INSTR(version_number,'.',1,2) AS sep2
  FROM   table_name
)
ORDER BY major DESC, minor DESC, patch DESC
FETCH FIRST ROW ONLY;

或者,使用(较慢的)正则表达式:

SELECT version_number,
       TO_NUMBER(REGEXP_SUBSTR(version_number, '\d+', 1, 1)) AS major,
       TO_NUMBER(REGEXP_SUBSTR(version_number, '\d+', 1, 2)) AS minor,
       TO_NUMBER(REGEXP_SUBSTR(version_number, '\d+', 1, 3)) AS patch
FROM   table_name
ORDER BY major DESC, minor DESC, patch DESC
FETCH FIRST ROW ONLY;

其中,对于您的示例数据:

CREATE TABLE table_name (version_number) AS
SELECT  '6.40.123580' FROM DUAL UNION ALL
SELECT '10.10.114580' FROM DUAL UNION ALL
SELECT '10.10.114582' FROM DUAL;

两者输出:

VERSION_NUMBER MAJOR MINOR PATCH
10.10.114582 10 10 114582

如果您特别想使用MAX聚合函数,那么您可以使用MAX() KEEP ()只保留最大的组成部分:

SELECT MAX(version_number) KEEP (
         DENSE_RANK LAST ORDER BY
         TO_NUMBER(SUBSTR(version_number,        1, sep1 -    1)),
         TO_NUMBER(SUBSTR(version_number, sep1 + 1, sep2 - sep1)),
         TO_NUMBER(SUBSTR(version_number, sep2 + 1))
       ) AS max_version_number
FROM   (
  SELECT version_number,
         INSTR(version_number,'.',1,1) AS sep1,
         INSTR(version_number,'.',1,2) AS sep2
  FROM   table_name
);

其中,对于示例数据,输出:

MAX_VERSION_NUMBER
10.10.114582

db<>fiddle here