【问题标题】:Backwards hierarchy in OracleOracle中的向后层次结构
【发布时间】:2016-09-20 00:24:46
【问题描述】:

我有一张表(好吧,它是一个 CTE),我需要从中提取层次结构,除了 parent_id 之外,我有 child-id...

例如

Rule_ID | Group_Name | Function_ID | Info    | Child_ID
1         'ABC'        1             '1blah'   0
1         'ABC'        2             '2blah'   3
2         'ABC'        5             '5blah'   0
2         'ABC'        6             '6blah'   7
null      'ABC'        7             '7blah'   11
null      'ABC'        11            '11blah'  0

现在另一个问题是function_id作为组的一部分是唯一的,并且一个Rule_id不会出现在孩子身上,这是第n级。即,虽然 Function_ID = 3 存在,但它没有相同的 Rule_ID。

我需要的是:

Rule_ID | Group_Name | Function_ID | Info  
1         'ABC'        1             '1blah'
1         'ABC'        2             '2blah'
1         'ABC'        3             '3blah'
2         'ABC'        5             '5blah'
2         'ABC'        6             '6blah'
2         'ABC'        7             '7blah'
2         'ABC'        11            '11blah'

我尝试了标准的层次结构函数,但它们似乎都基于 Parent_ID 而不是 Child_ID 工作。

任何人都可以纠正我吗?

【问题讨论】:

  • 这个不清楚。在“期望的”输出中,有一行 Info 是 '3blah'。您输入的信息列中没有这样的值。那价值从何而来?然后:您在下面描述的输入内容很清楚(至少对我而言)-您是什么意思?为什么这一切都很重要?我相信确实如此,但你没有解释如何。

标签: sql oracle11g


【解决方案1】:

我认为这将满足您的需求,尽管我很确定有一种不那么笨重的方法......

WITH sample_data AS (SELECT 1 rule_id, 'ABC' group_name, 1 function_id, '1blah' info, 0 child_id FROM dual UNION ALL
                     SELECT 1 rule_id, 'ABC' group_name, 2 function_id, '2blah' info, 3 child_id FROM dual UNION ALL
                     SELECT 2 rule_id, 'ABC' group_name, 5 function_id, '5blah' info, 0 child_id FROM dual UNION ALL
                     SELECT 2 rule_id, 'ABC' group_name, 6 function_id, '6blah' info, 7 child_id FROM dual UNION ALL
                     SELECT NULL rule_id, 'ABC' group_name, 3 function_id, '3blah' info, 0 child_id FROM dual UNION ALL
                     SELECT NULL rule_id, 'ABC' group_name, 7 function_id, '7blah' info, 11 child_id FROM dual UNION ALL
                     SELECT NULL rule_id, 'ABC' group_name, 11 function_id, '11blah' info, 0 child_id FROM dual)
SELECT sd1.rule_id,
       sd1.group_name,
       sd1.function_id,
       (SELECT info FROM sample_data sd2 WHERE sd2.function_id = sd1.function_id) info
FROM   (SELECT rule_id,
               group_name,
               connect_by_root(function_id) function_id,
               connect_by_isleaf isleaf 
        FROM   sample_data sd
        CONNECT BY PRIOR function_id = child_id
                   AND PRIOR group_name = group_name) sd1
WHERE  isleaf = 1
ORDER BY rule_id, function_id;

   RULE_ID GROUP_NAME FUNCTION_ID INFO
---------- ---------- ----------- ------
         1 ABC                  1 1blah
         1 ABC                  2 2blah
         1 ABC                  3 3blah
         2 ABC                  5 5blah
         2 ABC                  6 6blah
         2 ABC                  7 7blah
         2 ABC                 11 11blah

记住:仅仅因为一列被标记为“child_id”并不意味着它不能是父 id...你只需要重新标记你脑海中的东西

【讨论】:

  • 您是否有根据地猜测 OP 意味着在他/她的输入中包含 sample_data 中的第五行(第一行为 NULL rul​​e_d)?我在那里没看到。
  • 是的,根据 OP 所说的:ie, while Function_ID = 3 exists, it doesn't have the same Rule_ID
  • 完美。就像你说的,@Boneist,我对它的逻辑很感兴趣。
猜你喜欢
  • 2020-04-17
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多