connectbypreor:在向上钻取2层之前使用preor

f45qwnt8  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(307)

我有下面的connectbyprior sql,它基本上从叶节点开始,沿着树向上到父“tree trunc”(级别1):

with my_tree as (
   select 'level 4.1' node, 'level 3.1' parent_node from dual union
   select 'level 4.2' node, 'level 3.2' parent_node from dual union
   select 'level 3.1' node, 'level 2'   parent_node from dual union
   select 'level 3.2' node, 'level 2'   parent_node from dual union
   select 'level 2'   node, 'level 1'   parent_node from dual union
   select 'level 1'   node, ''          parent_node from dual
)
select level, t.node, t.parent_node, prior t.node child_that_pointed_me_here
from   my_tree t
connect by t.node = prior t.parent_node
start with t.node like 'level 4%'

它提供以下输出:

level node      parent_node child_who_pointed_me_here
----- --------- ----------- -------------------------
1     level 4.1 level 3.1 
2     level 3.1 level 2     level 4.1
3     level 2   level 1     level 3.1
4     level 1               level 2
1     level 4.2 level 3.2 
2     level 3.2 level 2     level 4.2
3     level 2   level 1     level 3.2
4     level 1               level 2

你可以看到说明书 prior t.node (别名为列) child_who_pointed_me_here )将我带到“prior”记录中的数据(即我开始的子节点),这正是我想要的。换言之 PRIOR 关键字使我可以访问“上一个”记录中的数据。
但我想访问的是以前的2级(或3级或4级)数据。像这样的 prior prior t.node . 所需的输出如下所示:

level node      parent_node child_who_pointed_me_here grandchild_who_pointed_me_here
----- --------- ----------- ------------------------- ------------------------------
1     level 4.1 level 3.1 
2     level 3.1 level 2     level 4.1
3     level 2   level 1     level 3.1                 level 4.1
4     level 1               level 2                   level 3.1
1     level 4.2 level 3.2
2     level 3.2 level 2     level 4.2
3     level 2   level 1     level 3.2                 level 4.2
4     level 1               level 2                   level 3.2

我试过明摆着的 prior prior t.node ,但它显然只会导致不受支持的语法类型错误。
因此,问题是:在connectbysql中是否有一个构造允许我沿着路径返回(或向上)两个级别?
我正在使用oracle12c来构建这个sql,但是可以用任何风格的sql来回答。

3vpjnl9f

3vpjnl9f1#

sys\u connect\u by\u路径将为您提供到达当前行的整个沿袭。
我在sys\u connect\u by\u路径上执行字符串操作,方法是反转并选择第二个“/”和第三个“/”的索引位置以提取中间的数据
使用这个字符串,我们可以使用下面的方法提取2层,如下所示。

with my_tree as (
   select 'level 4.1' node, 'level 3.1' parent_node from dual union
   select 'level 4.2' node, 'level 3.2' parent_node from dual union
   select 'level 3.1' node, 'level 2'   parent_node from dual union
   select 'level 3.2' node, 'level 2'   parent_node from dual union
   select 'level 2'   node, 'level 1'   parent_node from dual union
   select 'level 1'   node, ''          parent_node from dual
)
select level, t.node, t.parent_node, prior t.node child_that_pointed_me_here
       ,sys_connect_by_path(t.node,'/') as lineage
       ,rtrim(
        reverse(
         substr(
               reverse(sys_connect_by_path(t.node,'/'))
               ,instr(reverse(sys_connect_by_path(t.node,'/')),'/',1,2)
               ,instr(reverse(sys_connect_by_path(t.node,'/')),'/',1,3)
               -
               instr(reverse(sys_connect_by_path(t.node,'/')),'/',1,2)
               )
              )
        ,'/') as two_level_up
  from my_tree t
connect by t.node = prior t.parent_node
start with t.node like 'level 4%'

+-------+-----------+-------------+----------------------------+--------------------------------------+--------------+
| LEVEL |   NODE    | PARENT_NODE | CHILD_THAT_POINTED_ME_HERE |               LINEAGE                | TWO_LEVEL_UP |
+-------+-----------+-------------+----------------------------+--------------------------------------+--------------+
|     1 | level 4.1 | level 3.1   | null                       | /level 4.1                           |              |
|     2 | level 3.1 | level 2     | level 4.1                  | /level 4.1/level 3.1                 |              |
|     3 | level 2   | level 1     | level 3.1                  | /level 4.1/level 3.1/level 2         | level 4.1    |
|     4 | level 1   |             | level 2                    | /level 4.1/level 3.1/level 2/level 1 | level 3.1    |
|     1 | level 4.2 | level 3.2   |                            | /level 4.2                           |              |
|     2 | level 3.2 | level 2     | level 4.2                  | /level 4.2/level 3.2                 |              |
|     3 | level 2   | level 1     | level 3.2                  | /level 4.2/level 3.2/level 2         | level 4.2    |
|     4 | level 1   |             | level 2                    | /level 4.2/level 3.2/level 2/level 1 | level 3.2    |
+-------+-----------+-------------+----------------------------+--------------------------------------+--------------+

D小提琴https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=0448131cc387e52eab3126dfce0a7cde

相关问题