我有一个oracle表,它在varchar2列中存储以下类型的数据 -
1009-25-7-7-1-7-22-5-7
1009-25-7-7-1-7-22-5-9
1001-2-53
1001-2-53-57
1001-2-53-72
1001-2-53-76
1001-2-53-88
1001-2-53-13
1001-2-53-17
1001-2-53-25
现在我的要求是以数字方式对这些数据进行排序。我在这一列中有数千行,其中n级组合如上所述。知道我怎么能用数字排序这个。真的可以帮助我获得任何输入,因为我对此毫无头绪。以编程方式生成上面的数字系统,使得“数字1 - 数字2 - 数字3”,因此我需要首先根据“数字1”,然后“数字2”进行排序,依此类推。以上数据集的结果应为 -
1001-2-53
1001-2-53-13
1001-2-53-17
1001-2-53-25
1001-2-53-57
1001-2-53-72
1001-2-53-76
1001-2-53-88
1009-25-7-7-1-7-22-5-7
1009-25-7-7-1-7-22-5-9
答案 0 :(得分:0)
这非常野蛮,可能无法使用。看起来嵌套表可能会对该列执行您想要的操作。下面的示例使用一些内置的xml实用程序来拆分列并再次重新组合:
我把它与一堆切割粘贴在一起:
http://askankit.blogspot.ca/2009/04/use-xmlagg-in-oracle-to-concat-multiple.html https://forums.oracle.com/message/9408528
CREATE TABLE my_table(mycol varchar2(1024));
insert into my_table values('1009-25-7-7-1-7-22-5-7');
insert into my_table values('1009-25-7-7-1-7-22-5-9');
insert into my_table values('1001-2-53');
insert into my_table values('1001-2-53-57');
insert into my_table values('1001-2-53-72');
insert into my_table values('1001-2-53-76');
insert into my_table values('1001-2-53-88');
insert into my_table values('1001-2-53-13');
insert into my_table values('1001-2-53-17');
insert into my_table values('1001-2-53-25');
insert into my_table values('10');
insert into my_table values('2');
查询:
SELECT mycol, sort_string
FROM (
SELECT mycol
,SUBSTR(REPLACE(REPLACE(XMLAGG(XMLELEMENT("x", x) ORDER BY seq)
,'</x>'
)
,'<x>'
,'|'
)
,2 ) AS sort_string
FROM ( SELECT m.mycol
,TO_CHAR(EXTRACTVALUE(column_value,'inner'), '09999999') AS x
,ROWNUM AS seq
FROM my_table m
,TABLE(xmlsequence(xmltype(
'<outer>' ||
'<inner>' || REPLACE(mycol,'-','</inner><inner>') || '</inner>' ||
'</outer>'
).EXTRACT('outer/*')))
)
GROUP BY mycol
) ORDER BY sort_string
结果:
| MYCOL | SORT_STRING |
|------------------------|-------------------------------------------------------------------------------------------|
| 2 | 00000002 |
| 10 | 00000010 |
| 1001-2-53 | 00001001| 00000002| 00000053 |
| 1001-2-53-13 | 00001001| 00000002| 00000053| 00000013 |
| 1001-2-53-17 | 00001001| 00000002| 00000053| 00000017 |
| 1001-2-53-25 | 00001001| 00000002| 00000053| 00000025 |
| 1001-2-53-57 | 00001001| 00000002| 00000053| 00000057 |
| 1001-2-53-72 | 00001001| 00000002| 00000053| 00000072 |
| 1001-2-53-76 | 00001001| 00000002| 00000053| 00000076 |
| 1001-2-53-88 | 00001001| 00000002| 00000053| 00000088 |
| 1009-25-7-7-1-7-22-5-7 | 00001009| 00000025| 00000007| 00000007| 00000001| 00000007| 00000022| 00000005| 00000007 |
| 1009-25-7-7-1-7-22-5-9 | 00001009| 00000025| 00000007| 00000007| 00000001| 00000007| 00000022| 00000005| 00000009 |
答案 1 :(得分:0)
这是一个丑陋的正则表达式,通过添加前导零将每个1,2和3位数字转换为4位数字。如果数字长度超过4位,则必须添加更多替换。
select * from (
select that_column original, regexp_replace(regexp_replace(regexp_replace(replace(that_column,'-','--'),'(^|-)(\d{1})(-|$)','\1000\2\3'),'(^|-)(\d{2})(-|$)','\100\2\3'),'(^|-)(\d{3})(-|$)','\10\2\3') sortable
from that_table
) order by sortable;
由于oracle没有零宽度匹配,因此首先将每个' - '转换为' - ',这样数字可以匹配为 - ## - 具有固定的数字位数。因此,最里面的函数是replace(that_column,'-','--')
。
之后,在没有特定顺序的情况下,通过添加前导零将所选大小的数字组转换为更大的大小。将'(^|-)(\d{1})(-|$)'
替换为'\1000\2\3'
,将1位数组转换为4位数组,方法是添加3个前导零。