Oracle SQL 查找单元格中数字的最大数字
Oracle SQL Find max digit in number in cell
我有一个这样的专栏:
如何找到最大数字列? (我想 select 左列的最大数字并将其写入新列)
使用 ORACLE SQL
谢谢!!!
一种方法使用递归查询将数字拆分为数字。递归查询对此很方便:
with cte (col, val, pos, maxpos) as (
select col, substr(col, 1, 1), 1, length(col) from mytable
union all
select col, substr(col, pos + 1, 1), pos + 1, maxpos from cte where pos < maxpos
)
select col, max(val) max_digit
from cte
group by col
COL | MAX_DIGIT
------: | :--------
6453356 | 6
9999 | 9
65267 | 7
467533 | 7
134425 | 5
一个选项是使用分层查询和 REGEXP_SUBSTR()
函数,以便首先单独拆分每个数字,然后找到每个分组列值的最大数字值:
SELECT col, MAX( REGEXP_SUBSTR(col,'[^\d]',level) ) AS maxdigit
FROM t
CONNECT BY level <= LENGTH(col)
AND PRIOR SYS_GUID() IS NOT NULL
AND PRIOR col = col
GROUP BY col
你也可以使用暴力法:
select (case when column like '%9%' then 9
when column like '%8%' then 8
. . .
end)
我提到这个是因为这不一定需要递归查询。
像专业人士一样解决问题:
正在创建示例数据:
CREATE TABLE tab as
WITH t(col) AS
(
SELECT 134425 FROM dual UNION ALL
SELECT 6453356 FROM dual UNION ALL
SELECT 65267 FROM dual UNION ALL
SELECT 9999 FROM dual UNION ALL
SELECT 467533 FROM dual
)
SELECT * FROM t;
解决方案:
select * from tab,
lateral
(
select max(substr(col, level, 1)) max_digit
from dual
connect by level <= length(col)
)
输出:
但您可以更轻松、更短地完成:没有任何子查询、CTE 和 connect-by。
只需使用 translate
、length
和 rtrim
:
length(
rtrim(
translate(
translate('0123456789',your_number,' ')
,' 0123456789'
,'x '
)))-1 as max_number
Step-by-step 描述:
translate('0123456789',x,' ')
从“0123456789”中删除现有数字。让我们称之为 remove_existing
translate(remove_existing, ,' 0123456789','x ')
将 remove_existing 中的空格替换为 'x'。因此,您可以根据 X 的位置确定您的号码中存在哪些数字,例如 'x x x x xx' 表示您的号码中有“0 2 4 6 89”。我们称它为 existing_as_x
length(rtrim(existing_as_x))-1
删除右边的空格和 returns 长度,因此返回的 length-1 等于您要求的最大位数。
完整测试用例:
with t(x) as (
select * from table(sys.odcinumberlist(
134425,
6453356,
65267,
9999,
467533
))
)
select
x,
translate('0123456789',x,' ') remove_existing,
translate(
translate('0123456789',x,' ')
,' 0123456789','x '
) as existing_as_x,
length(
rtrim(
translate(
translate('0123456789',x,' ')
,' 0123456789'
,'x '
)))-1 as max_number
from t;
结果:
X REMOVE_EXISTING EXISTING_AS_X MAX_NUMBER
---------- ---------------- ------------- ----------
134425 0 6789 xxxxx 5
6453356 012 789 xxxx 6
65267 01 34 89 x xxx 7
9999 012345678 x 9
467533 012 89 xxxxx 7
我有一个这样的专栏:
如何找到最大数字列? (我想 select 左列的最大数字并将其写入新列)
使用 ORACLE SQL
谢谢!!!
一种方法使用递归查询将数字拆分为数字。递归查询对此很方便:
with cte (col, val, pos, maxpos) as (
select col, substr(col, 1, 1), 1, length(col) from mytable
union all
select col, substr(col, pos + 1, 1), pos + 1, maxpos from cte where pos < maxpos
)
select col, max(val) max_digit
from cte
group by col
COL | MAX_DIGIT ------: | :-------- 6453356 | 6 9999 | 9 65267 | 7 467533 | 7 134425 | 5
一个选项是使用分层查询和 REGEXP_SUBSTR()
函数,以便首先单独拆分每个数字,然后找到每个分组列值的最大数字值:
SELECT col, MAX( REGEXP_SUBSTR(col,'[^\d]',level) ) AS maxdigit
FROM t
CONNECT BY level <= LENGTH(col)
AND PRIOR SYS_GUID() IS NOT NULL
AND PRIOR col = col
GROUP BY col
你也可以使用暴力法:
select (case when column like '%9%' then 9
when column like '%8%' then 8
. . .
end)
我提到这个是因为这不一定需要递归查询。
像专业人士一样解决问题:
正在创建示例数据:
CREATE TABLE tab as
WITH t(col) AS
(
SELECT 134425 FROM dual UNION ALL
SELECT 6453356 FROM dual UNION ALL
SELECT 65267 FROM dual UNION ALL
SELECT 9999 FROM dual UNION ALL
SELECT 467533 FROM dual
)
SELECT * FROM t;
解决方案:
select * from tab,
lateral
(
select max(substr(col, level, 1)) max_digit
from dual
connect by level <= length(col)
)
输出:
但您可以更轻松、更短地完成:没有任何子查询、CTE 和 connect-by。
只需使用 translate
、length
和 rtrim
:
length(
rtrim(
translate(
translate('0123456789',your_number,' ')
,' 0123456789'
,'x '
)))-1 as max_number
Step-by-step 描述:
translate('0123456789',x,' ')
从“0123456789”中删除现有数字。让我们称之为remove_existing
translate(remove_existing, ,' 0123456789','x ')
将 remove_existing 中的空格替换为 'x'。因此,您可以根据 X 的位置确定您的号码中存在哪些数字,例如 'x x x x xx' 表示您的号码中有“0 2 4 6 89”。我们称它为existing_as_x
length(rtrim(existing_as_x))-1
删除右边的空格和 returns 长度,因此返回的 length-1 等于您要求的最大位数。
完整测试用例:
with t(x) as (
select * from table(sys.odcinumberlist(
134425,
6453356,
65267,
9999,
467533
))
)
select
x,
translate('0123456789',x,' ') remove_existing,
translate(
translate('0123456789',x,' ')
,' 0123456789','x '
) as existing_as_x,
length(
rtrim(
translate(
translate('0123456789',x,' ')
,' 0123456789'
,'x '
)))-1 as max_number
from t;
结果:
X REMOVE_EXISTING EXISTING_AS_X MAX_NUMBER
---------- ---------------- ------------- ----------
134425 0 6789 xxxxx 5
6453356 012 789 xxxx 6
65267 01 34 89 x xxx 7
9999 012345678 x 9
467533 012 89 xxxxx 7