需要一个Oracle分层查询,该查询只返回子项与搜索字符串匹配的记录的完整树
以下是此查询的完整示例数据集,其中没有任何节点与搜索字符串匹配,无需修剪树: Level parent id text --------------------------------------------- 0 0 1 toplevel 1 1 2 foo 1 1 3 sumthin else 1 1 4 foo 0 0 7 toplevel2 1 7 8 secondlevel 1 7 9 anothersecondlevel 级别父id文本 --------------------------------------------- 0 0 1顶级 1 1 2 foo 1 1 3其他 一一四福 0 0 7顶级2 1 7 8二级 1 7 9其他第二级 如果用户在“foo”上搜索,我需要返回以下内容: 0 0 1 toplevel 1 1 2 foo 1 1 4 foo 0 0 1顶级 1 1 2 foo 一一四福 实际情况稍微复杂一些(即,我想返回树中的三个级别),但这抓住了问题所在。在英语中,返回与搜索字符串匹配的节点的祖先树(从文本列上的匹配节点开始),并返回所有祖先 我是Oracle的新手(至少最近),尝试添加到CONNECT BY子句但未成功-始终返回以下内容: 1 1 2 foo 1 1 4 foo 1 1 2 foo 一一四福需要一个Oracle分层查询,该查询只返回子项与搜索字符串匹配的记录的完整树,oracle,hierarchical-trees,hierarchical-query,Oracle,Hierarchical Trees,Hierarchical Query,以下是此查询的完整示例数据集,其中没有任何节点与搜索字符串匹配,无需修剪树: Level parent id text --------------------------------------------- 0 0 1 toplevel 1 1 2 foo 1 1 3 sumthin else 1 1 4 foo 0
PS-oracle文档和示例表明,CONNECT_BY_ROOT将捕获祖先,但它似乎只返回顶级(ROOT)值。取决于您对级别列的使用(根据我的评论) 有关Oracle分层查询的信息: 如果级别为Oracle伪列,则返回您要求的内容:
WITH t AS (SELECT 0 AS parent,
1 AS id,
'toplevel' AS text FROM DUAL
UNION
SELECT 1 AS parent,
2 AS id,
'foo' AS text FROM DUAL
UNION
SELECT 1 AS parent,
3 AS id,
'sumthin else' AS text FROM DUAL
UNION
SELECT 1 AS parent,
4 AS id,
'foo' AS text FROM DUAL
UNION
SELECT 0 AS parent,
7 AS id,
'toplevel2' AS text FROM DUAL
UNION
SELECT 7 AS parent,
8 AS id,
'secondlevel' AS text FROM DUAL
UNION
SELECT 7 AS parent,
9 AS id,
'anothersecondlevel' AS text FROM DUAL
)
SELECT UNIQUE
level,
parent,
id,
text
FROM t
START WITH text = 'foo'
CONNECT BY PRIOR parent = id
ORDER BY parent;
返回:
LEVEL PARENT ID TEXT
2 0 1 toplevel
1 1 2 foo
1 1 4 foo
TLEVEL PARENT ID TEXT
0 0 1 toplevel
1 1 2 foo
1 1 4 foo
如果级别是表中的一列,则:
WITH t AS (SELECT 0 AS tlevel,
0 AS parent,
1 AS id,
'toplevel' AS text FROM DUAL
UNION
SELECT 1 AS tlevel,
1 AS parent,
2 AS id,
'foo' AS text FROM DUAL
UNION
SELECT 1 AS tlevel,
1 AS parent,
3 AS id,
'sumthin else' AS text FROM DUAL
UNION
SELECT 1 AS tlevel,
1 AS parent,
4 AS id,
'foo' AS text FROM DUAL
UNION
SELECT 0 AS tlevel,
0 AS parent,
7 AS id,
'toplevel2' AS text FROM DUAL
UNION
SELECT 1 AS tlevel,
7 AS parent,
8 AS id,
'secondlevel' AS text FROM DUAL
UNION
SELECT 1 AS tlevel,
7 AS parent,
9 AS id,
'anothersecondlevel' AS text FROM DUAL
)
SELECT UNIQUE
tlevel,
parent,
id,
text
FROM t
START WITH text = 'foo'
CONNECT BY PRIOR parent = id
ORDER BY parent;
返回:
LEVEL PARENT ID TEXT
2 0 1 toplevel
1 1 2 foo
1 1 4 foo
TLEVEL PARENT ID TEXT
0 0 1 toplevel
1 1 2 foo
1 1 4 foo
希望它有助于…自下而上遍历重要位是
连接之前的值的顺序(
)
order by
用于反转输出(因为根是foo),而distinct
删除重复的顶级值:
SELECT DISTINCT LEVEL, id, text
FROM t1
CONNECT BY PRIOR parent = id
START WITH text = 'foo'
ORDER BY LEVEL DESC
注意:如果您向foo添加一个子项并通过previor id=parent切换CONNCT,您将获得子项
如果您想查看整个层次结构,可以找到树的顶部
(通过查找没有父对象的行)
然后将其用作id开头(并反转外部查询中的树遍历顺序,id=parent):
我对“仅返回完整树的Oracle分层查询”部分的看法是:
SELECT Parent_ID
, Child_ID
, INITIAL_Parent_ID
, child_level
, INITIAL_Parent_ID || children_CHAIN AS CONNECTION_CHAIN
FROM ( SELECT CONNECT_BY_ROOT Parent_ID AS INITIAL_Parent_ID
, Parent_ID
, Child_ID
, LEVEL AS child_level
, SYS_CONNECT_BY_PATH(Child_ID, '/') AS children_chain
FROM REF_DECOMMISSIONS
CONNECT BY NOCYCLE Parent_ID = PRIOR Child_ID
)
WHERE INITIAL_Parent_ID NOT IN (SELECT Child_ID FROM REF_DECOMMISSIONS)
;
要将树过滤到包含特定子级的树,您需要在最后一个位置添加另一个条件以进一步过滤初始\u Parent\u ID。
查询将变成:
WITH ROOT_TREES AS
( SELECT Parent_ID
, Child_ID
, INITIAL_Parent_ID
, child_level
, INITIAL_Parent_ID || children_CHAIN AS CONNECTION_CHAIN
FROM ( SELECT CONNECT_BY_ROOT Parent_ID AS INITIAL_Parent_ID
, Parent_ID
, Child_ID
, LEVEL AS child_level
, SYS_CONNECT_BY_PATH(Child_ID, '/') AS children_chain
FROM REF_DECOMMISSIONS
CONNECT BY NOCYCLE Parent_ID = PRIOR Child_ID
)
WHERE INITIAL_Parent_ID NOT IN (SELECT Child_ID FROM REF_DECOMMISSIONS)
)
SELECT *
FROM root_trees
WHERE INITIAL_Parent_ID IN (SELECT INITIAL_Parent_ID
FROM root_trees
WHERE Child_ID = 123)
;
您是将LEVEL引用为分层伪列还是表中的列?我刚才问了一个类似的问题-也许其中的一些答案将有助于扭转连接的感觉,因为它为我提供了正确的结果集。仍在努力正确排序,因为从底部遍历树的更改似乎覆盖了对输出进行排序的任何尝试,从而使树仍然保持在一个连续的集合中。不确定排序为什么不起作用,也许您需要从顶部遍历到底部?现在已设置了排序和消除重复。谢谢大家的帮助!