列的最大值
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
在我的 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