2014-09-20 36 views
0

在Oracle 10g中,我有以下分級表:獲取父數據,如果子數據是Oracle階層表空

corp_id, parent_corp_id, col1, col2, col3 

我想變平的結構,使得我們得到的第一行的數據,其中COL1 OR col2或col3不爲空。

因此,舉例來說,假設我有:

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 

此查詢的結果會給我:

corp_id, parent_corp_id, col1, col2, col3 
3  , 1    , 5 , NULL, NULL 

另一種情形: 假設我把COL2 = 6,其中corp_id = 3

那麼,結果集應該是:

corp_id, parent_corp_id, col1, col2, col3 
3  , 1    , NULL, 6, NULL 

換句話說,如果孩子在這三列中有一列有數據,我們就抓住它。否則,我們嘗試父母等,等等。不應該超過3個級別,但可以有3個級別進行研究。

對分層查詢來說很新,所以如果這是一個基本問題,請原諒我。

回答

0

使用coalesce()功能,在其列表返回第一個非空值:

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 

獲得「具有非空值的第一行」,添加:

where coalesce(c.col1, p.col1, c.col2, p.col2, c.col3, p.col3) is not null 
and rownum = 1 
+0

這對我不起作用我很害怕,我需要一個分層查詢,因爲我不知道有多少層次需要去找,直到找到一個值... – mlnyc 2014-09-20 14:39:49

+0

@mlnyc is there an上限的水平? – Bohemian 2014-09-20 15:53:14

0

您確實需要使用hiearchial查詢(w/connect by子句),因爲您有一個具有子項的父項,並且該子項是另一個子項的父項(儘管您的示例數據沒有將其帶入播放),但是要求您顯示'first not null col1'和'first not null col2「等是與分層關係完全不同的問題。

請嘗試以下操作,爲了便於說明,我在小提琴中添加了一些其他示例數據(請檢查左側的DDL)。

它看起來像你期望的輸出,你不想顯示最高級別的父母,這就是爲什麼我把「where s.parent_corp_id不爲空」在最後。如果你確實想要展示這些,請把這條線路拿出來。

否則,這將顯示基於它們的組的col1/col2/col3值。請注意,示例2中的父級如何爲高級父節點,其中4作爲子節點,4也是8的父節點。因此,corp_id 8和4是同一分支的一部分,因此它們顯示相同的col1/col2/col3值,根據您的要求,這些都是整個分支的第一個非空值。

小提琴: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 

如果不提供你基於我曾經請提供我在DDL中使用的數據的預期輸出的樣本數據預期輸出小提琴。