【问题标题】:Oracle hierarchy queryOracle层次结构查询
【发布时间】:2015-10-15 12:12:49
【问题描述】:

在互联网上搜索了几天,寻找解决这个等级之谜的方法,但没有运气。我发现的所有解决方案要么有一行父 ID 为空,要么只有一个最终父级,要么我只是缺少一些知识,这些知识阻止我根据各种需求调整解决方案以满足我的需要。

数据如下所示:

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

【问题讨论】:

    标签: sql oracle11g hierarchical-data


    【解决方案1】:

    无论您从树的哪个位置开始,我都使用 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%' 
        ;
    

    【讨论】:

    • 感谢尼克。使用这个查询和我刚刚在帖子中编辑的去重、修改的数据样本,我看到了 Child =TYE2_B 的这个结果:3226 TYPE2_B 3225 TYPE2_A TYPE1_A 3226 TYPE2_B 3223 TYPE1_J TYPE1_J 3226 TYPE2_B 3225 TYPE2_A TYPE2_A
    • 忽略之前的评论,我是新手谢谢尼克。使用这个查询和我刚刚在帖子中编辑的去重、修改的数据样本,我得到了 Child = TYE2_B 的三个父母:TYPE1_A、TYPE1_J 和 TYPE2_A。子 TYPE2_B 应该只有两个最终父代:TYPE1_A 和 TYPE1_J。
    • 您能否进一步澄清您的数据?您有两个属于子记录的 Type1 记录。 SELECT 113,'TYPE1_L',91,'TYPE3_F' FROM DUAL 。此选择意味着记录 113 是 TYPE1 是 TYPE3 记录的子记录。
    • 113 是 PARENT_ID,TYPE1_L 是 PARENT。 TYPE3_F 是父 TYPE1_L 的子代。我错过了什么?
    • 对不起,在我的脑海里我读的是孩子,然后是父母。无论如何,解决方案已调整以适应。
    猜你喜欢
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多