我有一个自引用的表,带有id,parentid(引用id),名称,按列排序。
我想要做的是选择每个根的第一个叶节点,并将叶节点的id与根节点的名称配对。
数据可以具有无限级别,兄弟姐妹有一个订单(由“订购”列分配)。 “第一叶节点”是指第一个孩子的第一个孩子的第一个孩子(等等)孩子。
数据看起来像这样,兄弟姐妹通过订购排序:
一个
--a
--b
---- B.1
---- B.2
---- B.3
乙
--c
---- C.1
---- C.2
--D
ç
--e
---- E.1
------ E.1.1
我希望能够按如下方式生成映射:
A的名称,a的id
B的名称,c.1的id
C的名称,e.1.1的身份号
这是我用来实现这个目的的sql,但是我不太确定它是否会在无限级别上正确递归:
select id,
connect_by_root name name
from table
where connect_by_isleaf = 1
and ((level = 2 and ordering = 1)
or (level > 2 and ordering = 1 and prior ordering = 1))
start with parentid is null
connect by prior id = parentid;
有什么方法可以重写sql使其无限制?
答案 0 :(得分:2)
我会使用子查询:
SQL> SELECT root_name, MIN(leaf_name) first_leaf
2 FROM (SELECT id, connect_by_root(r.NAME) root_name, r.NAME leaf_name
3 FROM recurse r
4 WHERE connect_by_isleaf = 1
5 START WITH parentid IS NULL
6 CONNECT BY PRIOR id = parentid)
7 GROUP BY root_name;
ROOT_NAME FIRST_LEAF
---------- ----------
A a
B c.1
C e.1.1
这将为您提供每个根的第一个叶子(按叶名称排序)。
这是我用来生成数据的脚本:
CREATE TABLE recurse (
ID NUMBER PRIMARY KEY,
name VARCHAR2(10),
parentid NUMBER REFERENCES recurse (ID));
INSERT INTO recurse VALUES (1, 'A', '');
INSERT INTO recurse VALUES (3, 'b', 1);
INSERT INTO recurse VALUES (4, 'b.1', 3);
INSERT INTO recurse VALUES (5, 'b.2', 3);
INSERT INTO recurse VALUES (6, 'b.3', 3);
INSERT INTO recurse VALUES (7, 'B', '');
INSERT INTO recurse VALUES (8, 'c', 7);
INSERT INTO recurse VALUES (9, 'c.1', 8);
INSERT INTO recurse VALUES (10, 'c.2', 8);
INSERT INTO recurse VALUES (11, 'd', 7);
INSERT INTO recurse VALUES (12, 'C', '');
INSERT INTO recurse VALUES (13, 'e', 12);
INSERT INTO recurse VALUES (14, 'e.2', 13);
INSERT INTO recurse VALUES (15, 'e.1', 13);
INSERT INTO recurse VALUES (16, 'a', 1);
INSERT INTO recurse VALUES (20, 'e.1.1', 15);
正如你所看到的,我预计你的订购不会是名字(虽然你的问题确实不清楚)。
现在假设您想按ID(或任何其他列无关紧要)进行排序,您希望使用分析,例如:
SQL> SELECT DISTINCT root_name,
2 first_value(leaf_name)
3 over(PARTITION BY root_name ORDER BY ID) AS first_leaf_name
4 FROM (SELECT id, connect_by_root(r.NAME) root_name, r.NAME leaf_name
5 FROM recurse r
6 WHERE connect_by_isleaf = 1
7 START WITH parentid IS NULL
8 CONNECT BY PRIOR id = parentid)
9 ORDER BY root_name;
ROOT_NAME FIRST_LEAF_NAME
---------- ---------------
A b.1
B c.1
C e.2