San*_*non 8 sql sorting oracle decimal-point oracle10g
更新:
ORACLE VERSION 10G
我有一个Oracle如下记录列表,这些记录实际上是各种书籍
的部分.记录以下面的格式生成
[主题].[子主题].[第一级] ....... [最后一级]
Sections
--------
1
7.1
6.2
7.1
7.4
6.8.3
6.8.2
10
1.1
7.6
6.1
11
8.3
8.5
1.1.2
6.4
6.6
8.4
1.1.6
6.8.1
7.7.1
7.5
7.3
Run Code Online (Sandbox Code Playgroud)
我想订购如下
1
1.1
1.1.2
1.1.6
6.2
6.4
6.5
6.6
6.7
6.8.1
6.8.2
6.8.3
7.2
7.3
7.4
7.5
7.6
7.7.1
7.7.2
8.3
8.4
8.5
10
Run Code Online (Sandbox Code Playgroud)
但由于该字段不是numeric datatype排序结果,所以这样的东西
1
10
1.1
1.1.2
1.1.6
....
.....
8.5
Run Code Online (Sandbox Code Playgroud)
我怎样才能对它们进行排序 由于多个小数点,我无法将它们转换为数字.
是否有任何功能oracle支持这种分类技术
当已知最大深度时,您可以在子部分中拆分该部分:
SQL> SELECT SECTION FROM DATA
2 ORDER BY to_number(regexp_substr(SECTION, '[^.]+', 1, 1)) NULLS FIRST,
3 to_number(regexp_substr(SECTION, '[^.]+', 1, 2)) NULLS FIRST,
4 to_number(regexp_substr(SECTION, '[^.]+', 1, 3)) NULLS FIRST;
SECTION
-------
1
1.1
1.1.2
1.1.6
6.1
6.2
[...]
8.5
10
11
Run Code Online (Sandbox Code Playgroud)
如果子节的最大深度未知(但可能在8位字符数据库上少于几百或在ANSI字符数据库中少于几千),您可以定义一个将不可分类的数字转换为可排序字符的函数:
SQL> CREATE OR REPLACE FUNCTION order_section (p_section VARCHAR2)
2 RETURN VARCHAR2 IS
3 l_result VARCHAR2(4000);
4 BEGIN
5 FOR i IN 1..regexp_count(p_section, '[^.]+') LOOP
6 l_result := l_result
7 || CASE WHEN i > 1 THEN '.' END
8 || CHR(64+regexp_substr(p_section, '[^.]+', 1, i));
9 END LOOP;
10 RETURN l_result;
11 END;
12 /
Function created
SQL> SELECT SECTION, order_section(SECTION)
2 FROM DATA
3 ORDER BY 2;
SECTION ORDER_SECTION(SECTION)
------- -------------------------
1 A
1.1 A.A
1.1.2 A.A.B
1.1.6 A.A.F
6.1 F.A
6.2 F.B
[...]
8.5 H.E
10 J
11 K
Run Code Online (Sandbox Code Playgroud)
如果级别数是固定的(例如最多 4 个),您可以使用以下级别:
ORDER BY
TO_NUMBER(REGEXP_SUBSTR(Sections, '\d+', 1, 1)) NULLS FIRST,
TO_NUMBER(REGEXP_SUBSTR(Sections, '\d+', 1, 2)) NULLS FIRST,
TO_NUMBER(REGEXP_SUBSTR(Sections, '\d+', 1, 3)) NULLS FIRST,
TO_NUMBER(REGEXP_SUBSTR(Sections, '\d+', 1, 4)) NULLS FIRST
Run Code Online (Sandbox Code Playgroud)