甲骨文 |递归查找所有父级并返回以逗号分隔的结果

问题描述 投票:0回答:1

我在预言机中有下表:

P_C_REL (Child , Parent ,Ownership)

Child|Parent|Ownership
41203134|10151091|100
10250181|40001104|30
40856701|40109963|100
10159060|40001104|100
41328372|10250181|100
40001471|10159060|100
10250181|40001471|70
10151091|40856701|100
40001104|10351678|100

一个孩子可以有多个父母,每个不同的父母都会导致不同的路径,直到最终父母

我需要 child 、RecursiveParents 、 Path 的输出 假设 41203134 和 41328372 是我的基子。

期望结果1:获取所有路径

41203134 | 41203134,10151091,40856701 | Path1
41328372 | 41328372,10250181,40001104,10351678 | Path1
41328372 | 41328372,10250181,40001471,10159060,40001104,10351678 | Path2

期望结果2:获得拥有最高所有权的路径

41203134 | 41203134,10151091,40856701 | Path1
41328372 | 41328372,10250181,40001471,10159060,40001104,10351678 | Path2

这在 Oracle 19c 中怎么可能?

我构建的查询如下

WITH    REL_TABLE(child, parent) AS
        (
        SELECT  child, parent
        FROM    P_C_REL p WHERE
           parent NOT IN
        (
            SELECT  child
            FROM    P_C_REL 
        ) 
        UNION ALL
        SELECT  p.child, a.parent
        FROM    REL_TABLE a 
        JOIN    P_C_REL p
        ON      p.parent= a.child
        )
SELECT  *
FROM    REL_TABLE
where child IN (41328372,42154684) 

错误

ORA-32044: cycle detected while executing recursive WITH query
sql oracle hierarchy recursive-query oracle19c
1个回答
0
投票

使用分层查询:

SELECT CONNECT_BY_ROOT child AS child,
       SUBSTR(SYS_CONNECT_BY_PATH(child, ',' ), 2) AS path
FROM   p_c_rel
WHERE CONNECT_BY_ISLEAF = 1
START WITH child IN (41203134, 41328372)
CONNECT BY child = PRIOR parent

对于样本数据:

CREATE TABLE P_C_REL (Child , Parent ,Ownership) AS
SELECT 41203134, 10151091, 100 FROM DUAL UNION ALL
SELECT 10250181, 40001104,  30 FROM DUAL UNION ALL
SELECT 40856701, 40109963, 100 FROM DUAL UNION ALL
SELECT 10159060, 40001104, 100 FROM DUAL UNION ALL
SELECT 41328372, 10250181, 100 FROM DUAL UNION ALL
SELECT 40001471, 10159060, 100 FROM DUAL UNION ALL
SELECT 10250181, 40001471,  70 FROM DUAL UNION ALL
SELECT 10151091, 40856701, 100 FROM DUAL UNION ALL
SELECT 40001104, 10351678, 100 FROM DUAL;

输出:

孩子 路径
41203134 41203134,10151091,40856701
41328372 41328372,10250181,40001104
41328372 41328372,10250181,40001471,10159060,40001104

或者,递归查询:

WITH path (root, path, parent, ownership) AS (
  SELECT child, TO_CHAR(child), parent, ownership
  FROM   p_c_rel
  WHERE  child IN (41203134, 41328372)
UNION ALL
  SELECT p.root, p.path || ',' || r.child, r.parent, p.ownership + r.ownership
  FROM   path p
         INNER JOIN p_c_rel r
         ON p.parent = r.child
)
SELECT root, path, ownership
FROM   path
ORDER BY DENSE_RANK() OVER (PARTITION BY root ORDER BY ownership DESC)
FETCH FIRST ROW WITH TIES;

哪个输出:

路径 所有权
41203134 41203134,10151091,40856701 300
41328372 41328372,10250181,40001471,10159060,40001104 470

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.