所有人。
我想在Oracle SQL中将数字的各个数字按数字顺序排序,即从648513到134568。
请帮助我摆脱困境。
答案 0 :(得分:2)
如果要处理具有多行的表中的数据,则仅采用单个输入的其他方法可能无法扩展为多个输入。
您可以创建一个简单的函数来执行排序:
Oracle设置:
CREATE FUNCTION sortNumber( value IN NUMBER ) RETURN NUMBER
IS
str VARCHAR2(40) := TO_CHAR( value );
chars SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST();
BEGIN
IF value IS NULL THEN
RETURN NULL;
END IF;
chars.EXTEND( LENGTH( str ) );
FOR i IN 1 .. LENGTH( str ) LOOP
chars(i) := TO_NUMBER( SUBSTR( str, i, 1 ) );
END LOOP;
SELECT LISTAGG( COLUMN_VALUE ) WITHIN GROUP ( ORDER BY COLUMN_VALUE )
INTO str
FROM TABLE( chars );
RETURN TO_NUMBER( str );
END;
/
CREATE TABLE test_data ( value ) AS
SELECT 634251 FROM DUAL UNION ALL
SELECT 9294241135337 FROM DUAL;
查询:
SELECT value,
sortNumber( value )
FROM test_data;
输出:
VALUE | SORTNUMBER(VALUE) ------------: | ----------------: 634251 | 123456 9294241135337 | 1122333445799
查询2 :
您也可以使用相关子查询在不使用函数的情况下进行操作:
SELECT value,
(
SELECT LISTAGG( SUBSTR( t.value, LEVEL, 1 ) )
WITHIN GROUP ( ORDER BY SUBSTR( t.value, LEVEL, 1 ) )
FROM DUAL
CONNECT BY LEVEL <= LENGTH( t.value )
) AS ordered_value
FROM test_data t
输出:
VALUE | ORDERED_VALUE ------------: | :------------ 634251 | 123456 9294241135337 | 1122333445799
db <>提琴here
答案 1 :(得分:1)
如果您希望通过根据数字的值替换每个数字来对数字进行排序,请尝试以下操作:
define val= 648513;
SELECT
LISTAGG(REGEXP_SUBSTR('&val', '(\d)', LEVEL), '') WITHIN GROUP(
ORDER BY
1
)
FROM
DUAL
CONNECT BY
LEVEL <= LENGTH('&val');
-- Output --
ORDERED_NUMBER
-------------------
134568
干杯!
答案 2 :(得分:0)
根据您的示例:
SQL> with test (col) as
2 (select 648513 from dual)
3 ,
4 -- split input value into rows
5 torows as
6 (select regexp_substr(col, '\d', 1, level) val
7 from test
8 connect by level <= length(col)
9 )
10 -- sort values and aggregate them back
11 select listagg(val, '') within group (order by to_number(val)) result
12 from torows;
RESULT
--------------------------------------------------------------------------------
134568
SQL>