Oracle层次结构查询

时间:2015-07-24 18:04:29

标签: sql oracle11g hierarchical-data

搜索互联网几天寻找这个等级谜语的解决方案,但没有运气。我找到的所有解决方案都有一行父ID为null,只有一个最终父级,或者我只是缺少一些知识,这些知识阻止我根据需要调整解决方案以满足我的需要。< / p>

数据如下所示:

SELECT 3225 PARENT_ID,'TYPE2_A' PARENT,3227 CHILD_ID,'TYPE2_C' CHILD FROM  DUAL UNION ALL
SELECT 148,'TYPE2_H',150,'TYPE2_G' FROM  DUAL UNION ALL
SELECT 3225,'TYPE2_A',3226,'TYPE2_B' FROM  DUAL UNION ALL
SELECT 3227,'TYPE2_C',3222,'TYPE3_E' FROM  DUAL UNION ALL
SELECT 3220,'TYPE3_D',3221,'TYPE3_I' FROM  DUAL UNION ALL
SELECT 3226,'TYPE2_B',3220,'TYPE3_D' FROM  DUAL UNION ALL
SELECT 2379,'TYPE1_K',148,'TYPE2_H' FROM  DUAL UNION ALL
SELECT 113,'TYPE1_L',91,'TYPE3_F' FROM  DUAL UNION ALL
SELECT 148,'TYPE2_H',128,'TYPE3_N' FROM  DUAL UNION ALL
SELECT 3223,'TYPE1_J',3226,'TYPE2_B' FROM  DUAL UNION ALL
SELECT 2379,'TYPE1_K',150,'TYPE2_G' FROM  DUAL UNION ALL
SELECT 150,'TYPE2_G',91,'TYPE3_F' FROM  DUAL UNION ALL
SELECT 2487,'TYPE1_A',3225,'TYPE2_A' FROM  DUAL UNION ALL
SELECT 98,'TYPE1_M',91,'TYPE3_F' FROM  DUAL;
  • TYPE1永远不会是孩子,它总是父母。
  • TYPE1可以是TYPE2或TYPE3的父级。
  • TYPE2可以是TYPE2或TYPE3的父级。
  • TYPE2永远不能是TYPE3的孩子。
  • TYPE3可以是TYPE3的父级。
  • TYPE2和TYPE3始终至少有一个TYPE1终极父级,但可以有多个TYPE1父级。

查询的目标是获取所有TYPE2和TYPE3子项的明确列表,如此...

SELECT PARENT FROM
(query from above)
WHERE PARENT LIKE 'TYPE2%' OR PARENT LIKE 'TYPE3%'
UNION
SELECT CHILD FROM
(query from above)
WHERE CHILD LIKE 'TYPE2%' OR CHILD LIKE 'TYPE3%';

...并找出他们的最终TYPE1父母是谁。

例如,基于上面的数据集......

  • TYPE3_F具有最终父母TYPE1_L和TYPE1_M
  • TYPE3_E具有最终父级TYPE1_A
  • TYPE2_B有最终父母TYPE1_A和TYPE1_J

输入TYPE3_F,TYPE3_E和TYPE2_B的结果集看起来像......

Child     Ultimate_Parent
TYPE3_F   TYPE1_L
TYPE3_F   TYPE1_M
TYPE3_E   TYPE1_A
TYPE2_B   TYPE1_A
TYPE2_B   TYPE1_J

1 个答案:

答案 0 :(得分:0)

我正在使用connect_by_root函数获取最高级别​​的父级,无论您在树中的哪个位置启动。

    with parent_child_data
    as
    (SELECT 2487    PARENT_ID,'TYPE1_A' PARENT, 3225 CHILD_ID,'TYPE2_A' CHILD FROM DUAL UNION ALL
    SELECT 3225 ,'TYPE2_A', 3226    ,'TYPE2_B' FROM DUAL UNION ALL
    SELECT 3225 ,'TYPE2_A', 3227    ,'TYPE2_C' FROM DUAL UNION ALL
    SELECT 3226 ,'TYPE2_B', 3220    ,'TYPE3_D' FROM DUAL UNION ALL
    SELECT 3227 ,'TYPE2_C', 3222    ,'TYPE3_E' FROM DUAL UNION ALL
    SELECT 113  ,'TYPE1_L', 91  ,'TYPE3_F' FROM DUAL UNION ALL
    SELECT 98   ,'TYPE1_M', 91  ,'TYPE3_F' FROM DUAL UNION ALL
    SELECT 2379 ,'TYPE1_K', 150 ,'TYPE2_G' FROM DUAL UNION ALL
    SELECT 2379 ,'TYPE1_K', 148 ,'TYPE2_H' FROM DUAL UNION ALL
    SELECT 150  ,'TYPE2_G', 1291    ,'TYPE3_F' FROM DUAL UNION ALL
    SELECT 148  ,'TYPE2_H', 150 ,'TYPE2_G' FROM DUAL UNION ALL
    SELECT 148  ,'TYPE2_H', 128 ,'TYPE3_N' FROM DUAL UNION ALL
    SELECT 150  ,'TYPE2_G', 1291    ,'TYPE3_F' FROM DUAL UNION ALL
    SELECT 3220 ,'TYPE3_D', 3221    ,'TYPE3_I' FROM DUAL UNION ALL
    SELECT 3226 ,'TYPE2_B', 3220    ,'TYPE3_D' FROM DUAL UNION ALL
    SELECT 3223 ,'TYPE1_J', 3226    ,'TYPE2_B' FROM DUAL UNION ALL
    SELECT 3225 ,'TYPE2_A', 3226    ,'TYPE2_B' FROM DUAL UNION ALL
    SELECT 2487 ,'TYPE1_A', 3225    ,'TYPE2_A' FROM DUAL)
    select * from (
select d.child_id, d.child, d.parent_id, d.parent, connect_by_root d.parent ultimate_parent
from parent_child_data d
where child like 'TYPE3%' or child like 'TYPE2%'
connect by prior child_id = parent_id)
where ultimate_parent like 'TYPE1%' 
    ;