Oracle - 在多个级别上自然排序行
使用Oracle 10.2.0。
我有一个由行号、缩进级别和文本组成的表格。我需要编写一个例程来“自然”地对缩进级别内的文本进行排序(即较低缩进级别的子级别)。我在分析例程和连接之前/之前的经验有限,但从我在这里和其他地方读到的内容来看,它们似乎可以用来帮助我的事业,但我不知道如何使用。
CREATE TABLE t (ord NUMBER(5), indent NUMBER(3), text VARCHAR2(254));
INSERT INTO t (ord, indent, text) VALUES (10, 0, 'A');
INSERT INTO t (ord, indent, text) VALUES (20, 1, 'B');
INSERT INTO t (ord, indent, text) VALUES (30, 1, 'C');
INSERT INTO t (ord, indent, text) VALUES (40, 2, 'D');
INSERT INTO t (ord, indent, text) VALUES (50, 2, 'Z');
INSERT INTO t (ord, indent, text) VALUES (60, 2, 'E');
INSERT INTO t (ord, indent, text) VALUES (70, 1, 'F');
INSERT INTO t (ord, indent, text) VALUES (80, 2, 'H');
INSERT INTO t (ord, indent, text) VALUES (90, 2, 'G');
INSERT INTO t (ord, indent, text) VALUES (100, 3, 'J');
INSERT INTO t (ord, indent, text) VALUES (110, 3, 'H');
此:
SELECT ord, indent, LPAD(' ', indent, ' ') || text txt FROM t;
...返回:
ORD INDENT TXT
---------- ---------- ----------------------------------------------
10 0 A
20 1 B
30 1 C
40 2 D
50 2 Z
60 2 E
70 1 F
80 2 H
90 2 G
100 3 J
110 3 H
选择了 11 行。
在我为您定义的情况下,我需要例程设置 ORD 60 = 50 和 ORD 50 = 60 [翻转它们],因为 E 在 D 之后 Z 之前。
与 ORD 80 和 90 相同 [90 带来 100 和 110,因为它们属于它]、100 和 110。最终输出应该是:
ORD INDENT TXT
10 0 A
20 1 B
30 1 C
40 2 D
50 2 E
60 2 Z
70 1 F
80 2 G
90 3 H
100 3 J
110 2 H
结果是每个缩进级别在其缩进级别内按字母顺序排序父级缩进级别。
Using Oracle 10.2.0.
I have a table that consists of a line number, an indent level, and text. I need to write a routine to 'natural' sort the text within an indent level [that is a child of a lower indent level]. I have limited experience with analytic routines and connect by/prior, but from what I've read here and elsewhere, it seems like they could be put to use to help my cause, but I can't figure out how.
CREATE TABLE t (ord NUMBER(5), indent NUMBER(3), text VARCHAR2(254));
INSERT INTO t (ord, indent, text) VALUES (10, 0, 'A');
INSERT INTO t (ord, indent, text) VALUES (20, 1, 'B');
INSERT INTO t (ord, indent, text) VALUES (30, 1, 'C');
INSERT INTO t (ord, indent, text) VALUES (40, 2, 'D');
INSERT INTO t (ord, indent, text) VALUES (50, 2, 'Z');
INSERT INTO t (ord, indent, text) VALUES (60, 2, 'E');
INSERT INTO t (ord, indent, text) VALUES (70, 1, 'F');
INSERT INTO t (ord, indent, text) VALUES (80, 2, 'H');
INSERT INTO t (ord, indent, text) VALUES (90, 2, 'G');
INSERT INTO t (ord, indent, text) VALUES (100, 3, 'J');
INSERT INTO t (ord, indent, text) VALUES (110, 3, 'H');
This:
SELECT ord, indent, LPAD(' ', indent, ' ') || text txt FROM t;
...returns:
ORD INDENT TXT
---------- ---------- ----------------------------------------------
10 0 A
20 1 B
30 1 C
40 2 D
50 2 Z
60 2 E
70 1 F
80 2 H
90 2 G
100 3 J
110 3 H
11 rows selected.
In the case I've defined for you, I need my routine to set ORD 60 = 50 and ORD 50 = 60 [flip them] because E is after D and before Z.
Same with ORD 80 and 90 [with 90 bringing 100 and 110 with it because they belong to it], 100 and 110. The final output should be:
ORD INDENT TXT
10 0 A
20 1 B
30 1 C
40 2 D
50 2 E
60 2 Z
70 1 F
80 2 G
90 3 H
100 3 J
110 2 H
The result is that each indent level is sorted alphabetically, within its indent level, within the parent indent level.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是我要做的工作。不知道在更大的集合上它的效率如何。对我来说最困难的部分是仅根据缩进和原始顺序来识别给定行的“父级”。
Here's what I got to work. No idea how efficient it might be on larger sets. The hard part for me was identifying the "parent" for a given row based solely on indent and original order.
好的,给你。数据结构中的困难部分是父节点不(明确)已知,因此查询的第一部分除了根据规则识别父节点之外什么也不做(对于每个节点,它获取所有子节点的一层深度,停止一旦标识小于或等于起始节点)。
其余的很简单,基本上只是一些带有 connect by 的递归,以按照您想要的顺序获取项目(动态地重新编号)。
Okay, here you go. The hard part in your data structure is that the parent is not (explicitly) known, so that the first part of the query does nothing but identify the parent according to the rules (for each node, it gets all subnodes one level deep, stopping as soon as the identation is smaller or equal to the start node).
The rest is easy, basically just some recursion with connect by to get the items in the order you want them (renumbering them dynamically).