Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要一个Oracle分层查询,该查询只返回子项与搜索字符串匹配的记录的完整树_Oracle_Hierarchical Trees_Hierarchical Query - Fatal编程技术网

需要一个Oracle分层查询,该查询只返回子项与搜索字符串匹配的记录的完整树

需要一个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

以下是此查询的完整示例数据集,其中没有任何节点与搜索字符串匹配,无需修剪树:

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 一一四福
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引用为分层伪列还是表中的列?我刚才问了一个类似的问题-也许其中的一些答案将有助于扭转连接的感觉,因为它为我提供了正确的结果集。仍在努力正确排序,因为从底部遍历树的更改似乎覆盖了对输出进行排序的任何尝试,从而使树仍然保持在一个连续的集合中。不确定排序为什么不起作用,也许您需要从顶部遍历到底部?现在已设置了排序和消除重复。谢谢大家的帮助!