Getting parent data if child data is null in Oracle hierarchical table
In Oracle 10g I have the following hierarchical table:
corp_id, parent_corp_id, col1, col2, col3
I want to flatten out the structure such that we get the first row's data where col1 OR col2 OR col3 is not null.
So for example, suppose I have:
corp_id = 1
parent_corp_id = null
col1 = 5
col2 = NULL
col3 = NULL
corp_id = 3
parent_corp_id = 1
col1 = NULL
col2 = NULL
col3 = NULL
the results of this query would give me:
corp_id, parent_corp_id, col1, col2, col3
3 , 1 , 5 , NULL, NULL
Another scenario: Suppose I put col2 = 6 where corp_id = 3
Well, then the result set should be:
corp_id, parent_corp_id, col1, col2, col3
3 , 1 , NULL, 6, NULL
In other words, if the child has data in one of these three columns we grab it. Otherwise, we try the parent and so on and so forth. Shouldn't be more than 3 levels deep but it could have 3 levels to look into.
Pretty new to hierarchical queries, so pardon me if this is a rudimentary question.
Use the coalesce()
function, which returns the first non-null value in its list:
select
c.corp_id,
c.parent_corp_id,
coalesce(c.col1, p.col1) col1,
coalesce(c.col2, p.col2) col2,
coalesce(c.col3, p.col3) col3
from mytable c
left join mytable p on p.corp_id = c.parent_corp_id
to get the "first row that has a not-null value", add:
where coalesce(c.col1, p.col1, c.col2, p.col2, c.col3, p.col3) is not null
and rownum = 1
You do need to use a hiearchial query (w/ the connect by clause) because of the fact that you have a parent with a child and that child is the parent of another child (although your example data doesn't bring that into play) however the requirement that you show the 'first not null col1' and the 'first not null col2' etc. is a separate issue from the hierarchical relationship altogether.
Try the following, I added some additional sample data to the fiddle (check the DDL on the left side) for illustrative purposes.
It looks like in your expected output you don't want to show the highest level parents, which is why I put "where s.parent_corp_id is not null" at the end. If you actually do want to show those, take that line out.
Otherwise, this will show the col1/col2/col3 values based on their group. Notice how in the example 2 is a high level parent and has 4 as a child, and 4 is also a parent of 8. So corp_id 8 and 4 are part of the same branch and they therefore show the same col1/col2/col3 values, and those are, based on your requirements, the first not null value of each throughout the branch.
Fiddle: http://sqlfiddle.com/#!4/ef218/14/0
with sub as
(select corp_id,
parent_corp_id,
col1,
col2,
col3,
level as lvl,
rownum - level as grp
from tbl
connect by prior corp_id = parent_corp_id
start with parent_corp_id is null),
col1_lvl as
(select grp, col1
from sub s
where s.lvl = (select min(x.lvl)
from sub x
where x.col1 is not null
and x.grp = s.grp)),
col2_lvl as
(select grp, col2
from sub s
where s.lvl = (select min(x.lvl)
from sub x
where x.col2 is not null
and x.grp = s.grp)),
col3_lvl as
(select grp, col3
from sub s
where s.lvl = (select min(x.lvl)
from sub x
where x.col3 is not null
and x.grp = s.grp))
select s.corp_id, s.parent_corp_id, c1.col1, c2.col2, c3.col3
from sub s
left join col1_lvl c1
on s.grp = c1.grp
left join col2_lvl c2
on s.grp = c2.grp
left join col3_lvl c3
on s.grp = c3.grp
where s.parent_corp_id is not null
If this doesn't provide the output you're expecting based on the sample data I used please provide the expected output for the data I used in the DDL on the fiddle.
链接地址: http://www.djcxy.com/p/93916.html上一篇: 取消分层数据