Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 用后面更高的数字替换数字的数字_Sql_Regex_Oracle - Fatal编程技术网

Sql 用后面更高的数字替换数字的数字

Sql 用后面更高的数字替换数字的数字,sql,regex,oracle,Sql,Regex,Oracle,给定一个数字,我想用下一个更大的数字替换每个数字。如果没有下一个更大的数字,请保留原来的数字 例如:输入:1234,输出-2344 因为在Oracle中,我们可以逐行处理所有内容,所以我首先尝试使用下面的查询将数字分隔成行 SELECT REGEXP_SUBSTR ('1234','[[:digit:]]',1,LEVEL) txt FROM dual CONNECT BY LEVEL <= length('1234'); 但是我被困在这里,如何比较这两行并用最大的替换它们 试图根据评论

给定一个数字,我想用下一个更大的数字替换每个数字。如果没有下一个更大的数字,请保留原来的数字

例如:输入:1234,输出-2344

因为在Oracle中,我们可以逐行处理所有内容,所以我首先尝试使用下面的查询将数字分隔成行

SELECT REGEXP_SUBSTR ('1234','[[:digit:]]',1,LEVEL) txt
FROM dual
CONNECT BY LEVEL <= length('1234');
但是我被困在这里,如何比较这两行并用最大的替换它们

试图根据评论进行扩展和澄清:

WITH t AS (
  SELECT LEVEL AS pos,
    ROWNUM AS txt_order,
    REGEXP_SUBSTR ('1245638','[[:digit:]]',1,LEVEL) AS txt
  FROM dual
  CONNECT BY LEVEL <= LENGTH('1245638')
),
v AS (
  SELECT t1.pos, t1.txt,
    MIN(t2.txt) KEEP (DENSE_RANK FIRST ORDER BY t2.pos) as new_txt
  FROM t t1
  LEFT JOIN t t2 ON t2.pos > t1.pos AND t2.txt > t1.txt
  GROUP BY t1.pos, t1.txt
)
SELECT LISTAGG(NVL(new_txt, txt), NULL) WITHIN GROUP (ORDER BY pos) AS OUTPUT
FROM v;

OUTPUT 
--------
2456888 
将数字视为一串数字。对于每个数字,找到当前数字右侧剩余数字中的第一个数字,该数字的值高于当前数字。这可能不是字符串中的最高值数字,甚至不是右边所有数字中的最高值,它只是遇到的第一个较高的值。如果没有更高的值,则保持当前数字不变。只考虑以下数字,前面的数字被忽略。

一些例子:

1234 -> 2344
1357 -> 3577
1157 -> 5577
1245638 -> 2456888
分解最后一个:

  • 数字1为
    1
    ;剩余字符串
    245638
    中高于
    1
    的第一个数字是
    2
  • 数字2为
    2
    ;剩余字符串
    45638
    中高于
    2
    的第一个数字是
    4
  • 数字3为
    4
    ;剩余字符串
    5638
    中高于
    4
    的第一个数字是
    5
  • 数字4为
    5
    ;剩余字符串
    638
    中高于
    5
    的第一个数字是
    6
  • 数字5为
    6
    ;剩余字符串
    38
    中高于
    6
    的第一个数字是
    8
  • 数字6为
    3
    ;剩余字符串
    8
    中高于
    3
    的第一个数字是
    8
  • 数字7为
    8
    ;没有后续数字高于
    8
    ,因此保留现有数字
    8

在评论中进行一些澄清后:

WITH t AS (
  SELECT LEVEL AS pos,
    ROWNUM AS txt_order,
    REGEXP_SUBSTR ('1245638','[[:digit:]]',1,LEVEL) AS txt
  FROM dual
  CONNECT BY LEVEL <= LENGTH('1245638')
),
v AS (
  SELECT t1.pos, t1.txt,
    MIN(t2.txt) KEEP (DENSE_RANK FIRST ORDER BY t2.pos) as new_txt
  FROM t t1
  LEFT JOIN t t2 ON t2.pos > t1.pos AND t2.txt > t1.txt
  GROUP BY t1.pos, t1.txt
)
SELECT LISTAGG(NVL(new_txt, txt), NULL) WITHIN GROUP (ORDER BY pos) AS OUTPUT
FROM v;

OUTPUT 
--------
2456888 

@Nicholas-所有小于5的数字都应替换为5。您输入的预期O/P为5557。@arunb2w。数字都是4位数吗?@Gordon-数字不限于4位数。可以有任意数量的数字。但它们都是整数,不是浮点数。Thanks@arunb2w-似乎仍然存在一些混乱,您的逻辑仅在评论中得到了真正的解释,因此我尝试在问题中进行总结。请检查一下我做对了。。。如果没有进一步澄清,或者回滚我的编辑*8-@arunb2w,请告诉我们这是为了什么-我好奇死了!亚历克斯-你真的很棒。对于唯一数字,您的查询看起来非常好,但由于with子句Order by txt,对于某些输入,它的行为出乎意料。例如,如果输入为“1245638”,则查询的输出为“2456688”,但预期的O/P为2456888,我认为您误解了我的问题。您的O/P显示您正在通过添加1替换每个数字,但我需要将每个数字替换为该数字中下一个最大的数字<代码>例如,在上述输入1245638中,1替换为==>下一个最大的数字2替换为==>下一个最大的数字4替换为==>下一个最大的数字5替换为==>下一个最大的数字6替换为==>下一个最大的数字8替换为==>下一个最大的数字8替换为==>没有下一个最大的数字所以8本身因此输出应该是2456888@arunb2w - 我不只是加1。第二个数字是2;原始数字中的第二大数字是3(第六位),而不是4。当它到达第六个数字,也就是3时,原始数字中第二个最大的数字是4,而不是8。您期望的结果将匹配起始编号1245688,而不是1245638。所以是的,我们中至少有一个人还不明白你的逻辑。。。也许你的意思是“下一个更大的数字”,而不是“下一个最大的数字”?对不起,我把你们弄糊涂了。@Alex,正如你说的,应该用下一个更大的数字替换它。也许上面解释我的要求的评论应该澄清你的疑问,我仍然不明白这是为了什么——但无论如何,我对这个答案投了赞成票!:)
ORIGINAL                                 OUTPUT 
---------------------------------------- --------
1234                                     2344     
1157                                     5577     
1357                                     3577     
1245638                                  2456888