Sql 对包含varchar形式的数字数据的oracle列进行排序?
我有一个oracle表,它在varchar2列中存储以下类型的数据-Sql 对包含varchar形式的数字数据的oracle列进行排序?,sql,string,oracle,sorting,numbers,Sql,String,Oracle,Sorting,Numbers,我有一个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个级别的组合。你知道我怎么用数字来排序吗。真的可以帮助我得到任何意
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
这相当残酷,可能无法使用。看起来嵌套表可以对该列执行所需的操作。下面的示例使用一些内置的xml实用程序将列拆分并重新组装:
- 将列更改为带有REPLACE和一些连接的xml字符串
- 使用xmlsequence从xml字符串构建xmltype 从xmltype中提取元素并将其视为行
- 使用8位数字格式转换每一行值(将此掩码扩展为最大宽度数字)
- 反转将行重新连接在一起的过程(排序字符串)
- 基于填充数字的订单
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
下面是一个丑陋的正则表达式,它通过添加前导零将每个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(即_列'-','-')
然后,不按特定顺序,通过添加前导零,将所选大小的数字组转换为更大的大小。将
'(^ |-)(\d{1})(|$)
替换为'\1000\2\3'
通过添加3个前导零将1个数字组转换为4个数字组。您需要定义排序逻辑,然后才能实现它。例如,您是否按第一个“元素”排序,然后按第二个,等等;三个元素的值总是比四个元素的值“低”;等等。包括对表/列的正确描述。还有,你所说的“数字”是什么意思?你的正常的orderby
子句发生了什么?
| 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 |
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;