Oracle中根据叶子从层次树中提取子树

问题描述

我有一个users 表示这样的分层树:

输入 评论
user_id 整数 序列
user_type 整数 1 组用户 2 普通用户
group_id 整数 引用user_type = 1同表的用户
user_name varchar(xxx)

group_id 列引用另一个 user_id,以便组和用户存储在同一个表中。

master group_id 为 0。

像这样:

user_id user_type group_id user_name
0 1 null '所有用户'
5 2 0 'USER1'
6 2 0 'USER2'
11 1 0 'SUBGROUP1'
12 1 11 'SUBGROUP2'
13 2 12 'USER3'
20 1 0 'SUBGROUP3'
21 2 20 'USER4'

请注意:

  • user_id 中可能存在间隙。
  • 一个群组可以不包含任何内容,也可以包含任意数量的群组或用户

我已经通过使用 connect by oracle 语句设法检索了完整的树,并正确缩进和排序。

这不是我的问题。

我的问题是:

一个查询的 user_id,如何将树浏览到主组“所有用户” 并作为结果输出从叶子到主组的完整路径?

示例 1:我运行 USER1 的查询,我想要以下输出

All Users
- USER1

示例 2:我对 USER3 运行相同的查询,我想要以下输出

All Users
- SUBGROUP1
-- SUBGROUP2
--- USER3

我希望有人能帮助我。

有关信息,我发布了检索完整树的查询,以便您了解 connect bystart with 的使用。 我确定这个查询与我想要的很接近,但我的尝试从未产生我想要的结果。

select 
  lpad('-',(level - 1) * 2,' ') || u.user_name as padded_name,u.userid,u.user_group,u.user_type,level
from users u
connect by prior u.user_id = u.group_id
start with u.user_id = 0
order siblings by upper(u.user_name);

解决方法

您可以使用 connect by 向相反的方向走。那么 level 当然也会相反。因此,要以正确的顺序和缩进获得结果,请根据这些结果链接另一个查询,该查询将使用 row_number() 来确定缩进:

with base as (
  select 
    u.user_name,u.user_id,u.group_id,u.user_type,level as lvl
  from users u
  connect by prior u.group_id = u.user_id
  start with u.user_id = 13
)
select 
  lpad('-',(row_number() over (order by lvl desc) - 1) * 2,' ') || base.user_name
    as padded_name,user_id,group_id,user_type
from base
order by lvl desc;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...