如何解决在分层查询中用父数据覆盖空值
pk fk parent
===== ====== ========
001 23 000
002 null 001
003 46 001
004 12 000
005 null 004
006 null 005
=====================
pk
是每一行的主键,fk
是另一个表的外键,稍后我将需要连接该表,而parent
是记录的层次结构父级。我可以使用
select
lpad(' ',2*level)||pk "primary_key",fk "foreign_key",sys_connect_by_path(pk,'/') "path"
from example_table
connect by prior pk = parent
;
我的问题是如何用最低祖先的行null
外键覆盖空值?在这种情况下,我的预期输出是
pk fk parent
========= ==== ======
001 23 000
002 23 001
003 46 001
004 12 000
005 12 004
006 12 005
====================
(填充主键以显示层次结构。)
解决方法
您可以使用标准的递归公用表表达式来表达这一点:
with cte (pk,fk,parent,lvl,pat) as (
select to_char(pk),to_char(pk) from mytable where parent = 0
union all
select lpad(' ',2 * (lvl + 1)) || t.pk,coalesce(t.fk,c.fk),t.parent,c.lvl + 1,c.pat || '/' || t.pk
from cte c
inner join mytable t on t.parent = c.pk
)
select pk,parent from cte order by pat
PK | FK | PARENT :---- | -: | -----: 1 | 23 | 0 2 | 23 | 1 3 | 46 | 1 4 | 12 | 0 5 | 12 | 4 6 | 12 | 5,
只需使用sys_connect_by_path(fk,'/')
来聚合父FK,然后使用regexp获取最后一个:
with example_table( pk,parent) as (
select '001',23,'000' from dual union all
select '002',null,'001' from dual union all
select '003',46,'001' from dual union all
select '004',12,'000' from dual union all
select '005','004' from dual union all
select '006','005' from dual
)
select
lpad(' ',2*level)||pk "primary_key",fk "foreign_key",nvl(fk,regexp_substr(sys_connect_by_path(fk,'/'),'(\d+)/*$',1,'',1)) fk2,sys_connect_by_path(pk,'/') "path"
from example_table
connect by prior pk = parent
;
结果:
primary_key foreign_key FK2 path
------------ ----------- ---------- --------------------------------------------------------------------------------
001 23 23 /001
002 23 /001/002
003 46 46 /001/003
004 12 12 /004
005 12 /004/005
006 12 /004/005/006
002 /002
003 46 46 /003
005 /005
006 /005/006
006 /006
11 rows selected.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。