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

Demo on DB Fiddle:

    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  

Demo

你也可以使用暴力法:

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。

只需使用 translatelengthrtrim:

length(
   rtrim(
      translate(
        translate('0123456789',your_number,'          ')
       ,' 0123456789'
       ,'x          '
       )))-1 as max_number

Step-by-step 描述:

  1. translate('0123456789',x,' ') 从“0123456789”中删除现有数字。让我们称之为 remove_existing
  2. translate(remove_existing, ,' 0123456789','x ') 将 remove_existing 中的空格替换为 'x'。因此,您可以根据 X 的位置确定您的号码中存在哪些数字,例如 'x x x x xx' 表示您的号码中有“0 2 4 6 89”。我们称它为 existing_as_x
  3. 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