从Oracle表

时间:2016-04-04 19:05:46

标签: oracle tree hierarchical-data recursive-query

我在Oracle中有两个用于表示各种树的表,这些表是:“PARTS_TREE_ENTRIES”,其中存储了所有节点(包括父节点和子节点),“PARTS_ITEMS”用于描述节点之间的关系

tables

在表格TREE_ITEMS中,列COMPONENT_ID表示父亲,COMPONENT_ITEMID表示其子女

有多个树,并且所有树的节点都在同一个表中“TREE_ENTRIES”为了更容易理解,这是几棵树的表示:

enter image description here

这些是他们在表格中的条目:

enter image description here

enter image description here

正如您在表TREE_ITEMS中看到的那样,作为分支根的节点具有COMPONENT_ID的值“A”

我需要帮助来构建一个查询,以获取最后一级的所有节点及其父节点及其ID的列表,输出应类似于以下内容:

enter image description here

我已经阅读了“连接方式”这一条款,但我从未使用它,我不知道从哪里开始。

非常感谢你!

1 个答案:

答案 0 :(得分:0)

我意识到你通过查询明确询问了连接,但我认为我们可以练习使用Recursive With SQL,因为它在一些附加功能上做同样的工作。

根据您的样本结果,我最好的猜测是这样的。

我不清楚你是想要连接数据还是分隔列,所以对这两种情况都有建议。

with tree_view(tree_id, component_id, component_itemid, id, part_tree_id, componentid, name, lvl, tree_path, root_id) as (
select t.tree_id, t.component_id, t.component_itemid, t.id, e.part_tree_id, e.componentid, e.name, 1, e.name, component_itemid
  from tree_items t,
       tree_entries e
 where t.component_itemid = e.componentid
   and t.tree_id = e.part_tree_id
   and t.component_id = 'A'
union all
select t.tree_id, t.component_id, t.component_itemid, t.id, e.part_tree_id, e.componentid, e.name, tv.lvl + 1, tv.tree_path || '=>' || e.name, tv.root_id
  from tree_items t,
       tree_entries e,
       tree_view tv
 where to_char(tv.component_itemid) = to_char(t.component_id)
       and to_char(e.componentid) = to_char(t.component_itemid)
       and tv.tree_id = t.tree_id
) -- end of hierarchy view
search depth first by lvl set order1
select tree_path,
       name,
       componentid,
       regexp_substr(tree_path, '[[:alpha:]]+', 1, 1) lvl1_part,
       regexp_substr(tree_path, '[[:alpha:]]+', 1, 2) lvl2_part,
       regexp_substr(tree_path, '[[:alpha:]]+', 1, 3) lvl3_part -- add more if there are further levels down the tree
  from (
        select tree_id, component_id, component_itemid, id, part_tree_id, componentid, name, lvl, tree_path, root_id, order1,
               case when lvl - lead(lvl) over (order by order1) < 0 then 0 else 1 end is_leaf
          from tree_view
       )
 where is_leaf = 1;

以下是使用您提供的数据在Oracle上执行的示例:

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 
Connected as sitja@orasitja

SQL> 
SQL> col tree_path format a40
SQL> col lvl1_part format a20
SQL> col lvl2_part format a20
SQL> col lvl3_part format a20
SQL> drop table tree_entries;
Table dropped
SQL> create table  tree_entries as
  2  with tree_entries(part_tree_id, componentid, name) as (
  3  select 1, 101, 'CLOCK' from dual union all
  4  select 1, 102, 'WATCH' from dual union all
  5  select 1, 105, 'BAND' from dual union all
  6  select 1, 113, 'MATERIAL' from dual union all
  7  select 1, 114, 'COLOR' from dual union all
  8  select 1, 106, 'CASE' from dual union all
  9  select 1, 115, 'MATERIAL' from dual union all
 10  select 1, 116, 'SHAPE' from dual union all
 11  select 1, 107, 'BEZEL' from dual union all
 12  select 1, 117, 'MATERIAL' from dual union all
 13  select 1, 118, 'TEXTURE' from dual union all
 14  select 1, 108, 'FACE' from dual union all
 15  select 1, 119, 'SHAPE' from dual union all
 16  select 1, 120, 'DESIGN' from dual union all
 17  select 2, 103, 'RELOJ' from dual union all
 18  select 2, 104, 'RELOJPULSERA' from dual union all
 19  select 2, 109, 'CORREA' from dual union all
 20  select 2, 121, 'MATERIAL' from dual union all
 21  select 2, 122, 'COLOR' from dual union all
 22  select 2, 110, 'CAJA' from dual union all
 23  select 2, 123, 'MATERIAL' from dual union all
 24  select 2, 124, 'FORMA' from dual union all
 25  select 2, 111, 'BISEL' from dual union all
 26  select 2, 125, 'MATERIAL' from dual union all
 27  select 2, 126, 'TEXTURA' from dual union all
 28  select 2, 112, 'CARATULA' from dual union all
 29  select 2, 127, 'FORMA' from dual union all
 30  select 2, 128, 'DISEÑO' from dual
 31  )
 32  select * from tree_entries;
Table created
SQL> drop table tree_items;
Table dropped
SQL> create table  tree_items as
  2  with tree_items(tree_id, component_id, component_itemid, id) as (
  3  select 1, 'A', 101, 1 from dual union all
  4  select 1, 'A', 102, 2 from dual union all
  5  select 1, '101', 107, 3 from dual union all
  6  select 1, '101', 108, 4 from dual union all
  7  select 1, '102', 105, 5 from dual union all
  8  select 1, '102', 106, 6 from dual union all
  9  select 1, '107', 117, 7 from dual union all
 10  select 1, '107', 118, 8 from dual union all
 11  select 1, '108', 119, 9 from dual union all
 12  select 1, '108', 120, 10 from dual union all
 13  select 1, '105', 113, 11 from dual union all
 14  select 1, '105', 114, 12 from dual union all
 15  select 1, '106', 115, 13 from dual union all
 16  select 1, '106', 116, 14 from dual union all
 17  select 2, 'A', 103, 15 from dual union all
 18  select 2, 'A', 104, 26 from dual union all
 19  select 2, '103', 111, 33 from dual union all
 20  select 2, '103', 112, 42 from dual union all
 21  select 2, '104', 109, 54 from dual union all
 22  select 2, '104', 110, 62 from dual union all
 23  select 2, '111', 125, 74 from dual union all
 24  select 2, '111', 126, 82 from dual union all
 25  select 2, '112', 127, 91 from dual union all
 26  select 2, '112', 128, 10 from dual union all
 27  select 2, '109', 127, 114 from dual union all
 28  select 2, '109', 122, 122 from dual union all
 29  select 2, '110', 123, 3334 from dual union all
 30  select 2, '110', 124, 141 from dual
 31  )
 32  select * from tree_items;
Table created
SQL> with tree_view(tree_id, component_id, component_itemid, id, part_tree_id, componentid, name, lvl, tree_path, root_id) as (
  2  select t.tree_id, t.component_id, t.component_itemid, t.id, e.part_tree_id, e.componentid, e.name, 1, e.name, component_itemid
  3    from tree_items t,
  4         tree_entries e
  5   where t.component_itemid = e.componentid
  6     and t.tree_id = e.part_tree_id
  7     and t.component_id = 'A'
  8  union all
  9  select t.tree_id, t.component_id, t.component_itemid, t.id, e.part_tree_id, e.componentid, e.name, tv.lvl + 1, tv.tree_path || '=>' || e.name, tv.root_id
 10    from tree_items t,
 11         tree_entries e,
 12         tree_view tv
 13   where to_char(tv.component_itemid) = to_char(t.component_id)
 14         and to_char(e.componentid) = to_char(t.component_itemid)
 15         and tv.tree_id = t.tree_id
 16  ) -- end of hierarchy view
 17  search depth first by lvl set order1
 18  select tree_path,
 19         name,
 20         componentid,
 21         regexp_substr(tree_path, '[[:alpha:]]+', 1, 1) lvl1_part,
 22         regexp_substr(tree_path, '[[:alpha:]]+', 1, 2) lvl2_part,
 23         regexp_substr(tree_path, '[[:alpha:]]+', 1, 3) lvl3_part -- add more if there are further levels down the tree
 24    from (
 25          select tree_id, component_id, component_itemid, id, part_tree_id, componentid, name, lvl, tree_path, root_id, order1,
 26                 case when lvl - lead(lvl) over (order by order1) < 0 then 0 else 1 end is_leaf
 27            from tree_view
 28         )
 29   where is_leaf = 1;
TREE_PATH                                NAME         COMPONENTID LVL1_PART            LVL2_PART            LVL3_PART
---------------------------------------- ------------ ----------- -------------------- -------------------- --------------------
CLOCK=>BEZEL=>MATERIAL                   MATERIAL             117 CLOCK                BEZEL                MATERIAL
CLOCK=>BEZEL=>TEXTURE                    TEXTURE              118 CLOCK                BEZEL                TEXTURE
CLOCK=>FACE=>SHAPE                       SHAPE                119 CLOCK                FACE                 SHAPE
CLOCK=>FACE=>DESIGN                      DESIGN               120 CLOCK                FACE                 DESIGN
WATCH=>BAND=>MATERIAL                    MATERIAL             113 WATCH                BAND                 MATERIAL
WATCH=>BAND=>COLOR                       COLOR                114 WATCH                BAND                 COLOR
WATCH=>CASE=>MATERIAL                    MATERIAL             115 WATCH                CASE                 MATERIAL
WATCH=>CASE=>SHAPE                       SHAPE                116 WATCH                CASE                 SHAPE
RELOJ=>BISEL=>MATERIAL                   MATERIAL             125 RELOJ                BISEL                MATERIAL
RELOJ=>BISEL=>TEXTURA                    TEXTURA              126 RELOJ                BISEL                TEXTURA
RELOJ=>CARATULA=>FORMA                   FORMA                127 RELOJ                CARATULA             FORMA
RELOJ=>CARATULA=>DISEÑO                  DISEÑO               128 RELOJ                CARATULA             DISEÑO
RELOJPULSERA=>CORREA=>COLOR              COLOR                122 RELOJPULSERA         CORREA               COLOR
RELOJPULSERA=>CORREA=>FORMA              FORMA                127 RELOJPULSERA         CORREA               FORMA
RELOJPULSERA=>CAJA=>MATERIAL             MATERIAL             123 RELOJPULSERA         CAJA                 MATERIAL
RELOJPULSERA=>CAJA=>FORMA                FORMA                124 RELOJPULSERA         CAJA                 FORMA
16 rows selected

SQL>