从oracle中的表中选择叶ID +根名称

时间:2010-08-23 03:31:37

标签: sql oracle hierarchical-data

我有一个自引用的表,带有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使其无限制?

1 个答案:

答案 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