我在预言机中有下表:
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
使用分层查询:
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 |