微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在分层查询中用父数据覆盖空值

如何解决在分层查询中用父数据覆盖空值

我有一个具有以下格式的表:

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

Demo on DB Fiddlde

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 举报,一经查实,本站将立刻删除。