2016-04-04 115 views
0

我在Oracle中有兩個表來表示各種樹,這些表是:「PARTS_TREE_ENTRIES」,其中存儲了所有的節點(包括父母和子女)和「PARTS_ITEMS」,這些節點描述了節點之間的關係從Oracle表建立一棵樹

tables

在表TREE_ITEMS列COMPONENT_ID代表父親和COMPONENT_ITEMID及其子

有一個以上的樹和各樣的樹的節點是在同一個表「TREE_ENTRIES」爲了使它更容易undestand這是交流的代表樹木ouple:

enter image description here

而這些都是他們的作品表中:

enter image description here

enter image description here

正如你可以看到表中TREE_ITEMS是根的節點的分支的值爲「A」COMPONENT_ID

我需要幫助建立一個查詢來獲取與父母和其ID的最後一個級別的所有節點的列表,輸出應該是類似以下內容:

enter image description here

我讀過有關的條款「通過「連接」,但我從來沒有使用過它,我不知道從哪裏開始。

非常感謝您提前!

+0

如果你的輸出始終在三級樹預測,也許你所選擇的模式是不是最貼切。 – symcbean

+0

http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking-a-question/285557#285557 –

+0

從知道樹只有三層,但最終可能會得到新的,這就是爲什麼我選擇這個模式,但我想聽聽你的理由。 –

回答

0

我意識到你明確詢問了通過查詢進行連接,但我認爲我們可以使用遞歸式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 [email protected] 

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> 
+0

嗨弗朗西斯科,你提出的解決方案完美的工作,雖然誠實地說,我努力去解決它,因爲我的SQL水平不是很好,我會花費一個有趣的時間分析它。謝謝! –