I have a table with the following format:
x
pk fk parent
===== ====== ========
001 23 000
002 null 001
003 46 001
004 12 000
005 null 004
006 null 005
=====================
pk
is the primary key for each row, fk
is a foreign key to another table I’ll need to join later, and parent
is the record’s hierarchical parent. I can create a hierarchical query on this data with
select
lpad(' ',2*level)||pk "primary_key",
fk "foreign_key",
sys_connect_by_path(pk,'/') "path"
from example_table
connect by prior pk = parent
;
My question is how do I overwrite a row’s null
foreign key with that of the lowest ancestor without a null? My intended output in this scenario is
pk fk parent
========= ==== ======
001 23 000
002 23 001
003 46 001
004 12 000
005 12 004
006 12 005
====================
(primary keys padded to show hierarchical structure.)
Advertisement
Answer
You could express this with a standard recursive common table expression:
with cte (pk, fk, parent, lvl, pat) as (
select to_char(pk), fk, parent, 0, 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, fk, 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