Oracle 不使用子查询和函数展平层次查询PLSQL
我是PLSQL新手,并开始学习如何以高效的方式编写查询。我面临着一个挑战,那就是如何使用Connect By将员工报告层次结构扁平化Oracle 不使用子查询和函数展平层次查询PLSQL,oracle,plsql,hierarchy,Oracle,Plsql,Hierarchy,我是PLSQL新手,并开始学习如何以高效的方式编写查询。我面临着一个挑战,那就是如何使用Connect By将员工报告层次结构扁平化 目前,我们在员工报告中有五个层次,但我们的查询不应限制为5个层次。将来,如果我们有新的lvel报告,相同的查询应该在不做任何更改的情况下工作 结果集中的所有记录应以同一级别结束,如果经理没有向他/她报告的员工,则第5级应为经理本身。为了更好地理解,您可以看到以下预期结果。示例:Mgr1和Mgr3 注意:为了获得更好的性能,我不想对此请求使用任何函数或子查询 预期结
Level 1 Level 2 Level 3 Level 4 Level 5 **(Level 6, Level 7 ) for future**
---------- ---------- ------- ------- ------ ------ -------
President VP1 Dir1 Mgr1 Mgr1
President VP1 Dir2 Mgr2 Emp1
President VP2 Dir3 Mgr4 Emp2
President VP2 Dir4 Mgr3 Mgr3
President VP3 Dir5 Mgr5 Emp3
President VP3 Dir6 Mgr6 Emp4
President VP4 Dir7 Mgr7 Emp5
在我看来,以下内容与您想要的一样:
with normalized$(super_id, emp_id) as (
select null, 'president' from dual
union all
select 'president', 'vp1' from dual
union all
select 'president', 'vp2' from dual
union all
select 'president', 'vp3' from dual
union all
select 'president', 'vp4' from dual
union all
select 'vp1', 'dir1' from dual
union all
select 'vp1', 'dir2' from dual
union all
select 'vp2', 'dir3' from dual
union all
select 'vp2', 'dir4' from dual
union all
select 'vp3', 'dir5' from dual
union all
select 'vp3', 'dir6' from dual
union all
select 'vp4', 'dir7' from dual
union all
select 'dir1', 'mgr1' from dual
union all
select 'dir2', 'mgr2' from dual
union all
select 'dir3', 'mgr4' from dual
union all
select 'dir4', 'mgr3' from dual
union all
select 'dir5', 'mgr5' from dual
union all
select 'dir6', 'mgr6' from dual
union all
select 'dir7', 'mgr7' from dual
union all
select 'mgr2', 'emp1' from dual
union all
select 'mgr4', 'emp2' from dual
union all
select 'mgr5', 'emp3' from dual
union all
select 'mgr6', 'emp4' from dual
union all
select 'mgr7', 'emp5' from dual
union all
-- note: these two are added here for testing the levels 6 and 7
select 'emp2', 'sub1' from dual
union all
select 'sub1', 'subsub1' from dual
),
denormalized$ as (
select ora_hash(emp_id) as hierarchy_id, -- note: this is just "some" row id; use whatever else you wish
sys_connect_by_path(emp_id, '|') as hierarchy
from normalized$ N
where connect_by_isleaf = 1
start with super_id is null
connect by prior emp_id = super_id
),
split$ as (
select hierarchy_id,
regexp_substr(hierarchy, '\|([^|]*)', 1, 1, null, 1) as h_lvl_1,
regexp_substr(hierarchy, '\|([^|]*)', 1, 2, null, 1) as h_lvl_2,
regexp_substr(hierarchy, '\|([^|]*)', 1, 3, null, 1) as h_lvl_3,
regexp_substr(hierarchy, '\|([^|]*)', 1, 4, null, 1) as h_lvl_4,
regexp_substr(hierarchy, '\|([^|]*)', 1, 5, null, 1) as h_lvl_5,
regexp_substr(hierarchy, '\|([^|]*)', 1, 6, null, 1) as h_lvl_6,
regexp_substr(hierarchy, '\|([^|]*)', 1, 7, null, 1) as h_lvl_7
from denormalized$
),
filled$ as (
select hierarchy_id,
h_lvl_1,
coalesce(h_lvl_2, h_lvl_1) as h_lvl_2,
coalesce(h_lvl_3, h_lvl_2, h_lvl_1) as h_lvl_3,
coalesce(h_lvl_4, h_lvl_3, h_lvl_2, h_lvl_1) as h_lvl_4,
coalesce(h_lvl_5, h_lvl_4, h_lvl_3, h_lvl_2, h_lvl_1) as h_lvl_5,
coalesce(h_lvl_6, h_lvl_5, h_lvl_4, h_lvl_3, h_lvl_2, h_lvl_1) as h_lvl_6,
coalesce(h_lvl_7, h_lvl_6, h_lvl_5, h_lvl_4, h_lvl_3, h_lvl_2, h_lvl_1) as h_lvl_7
from split$
)
select *
from filled$
;
。。。屈服于
HIERARCHY_ID H_LVL_1 H_LVL_2 H_LVL_3 H_LVL_4 H_LVL_5 H_LVL_6 H_LVL_7
------------ --------- ------- ------- ------- ------- ------- -------
490409852 president vp1 dir1 mgr1 mgr1 mgr1 mgr1
1220769441 president vp1 dir2 mgr2 emp1 emp1 emp1
849214331 president vp2 dir3 mgr4 emp2 sub1 subsub1
530886880 president vp2 dir4 mgr3 mgr3 mgr3 mgr3
1157603336 president vp3 dir5 mgr5 emp3 emp3 emp3
1467614544 president vp3 dir6 mgr6 emp4 emp4 emp4
523144703 president vp4 dir7 mgr7 emp5 emp5 emp5
然而,,如果没有返回sys.anyDataSet
的表函数,您不可能(据我所知)进行查询以返回任意数量的列,因此,如果上面的查询是7,我们只需坚持您的层次结构中假定的最大级别数
请注意通过路径连接连接及其后续拆分可以通过不同的方式完成,即使没有相对较慢的正则表达式。检查您自己的方式,选择最适合您的方式。您的示例不太清楚,如果正确格式化和对齐,并显示源数据,会有所帮助。如果要使用connect by,为什么要使用PL/SQL?为什么第6/7层是空的?根据您之前的逻辑,第一行的第6层和第7层条目不应该都是Mgr1吗?很抱歉,会解决这个问题并尝试改进格式,我们必须使用Connect解决这个问题,不限于PL/SQL,我只是保留了这两个级别(第6层和第7层)以供理解,在未来的Emp5中,可能会有一名进入6级的报告者,以此类推。。即使在这种情况下,我们的查询也会起作用。然后结果集中的所有其他行的第5级值都会重复为第6级?请编辑您的问题,以包含反映您期望得到的输出的示例输入数据?编写“按查询连接”很简单(此站点按原样)。然而,默认悬垂叶子的要求非常严格,我不知道如果没有函数或子查询,你怎么能做到这一点。那么,这是你家庭作业的实际要求还是你对自己施加的额外限制?谢谢你在这方面的帮助