2016-07-06 75 views
1

我有以下表結構。我想從TAB2的每個級別獲得總和。在每個級別的層次結構查詢總和

TAB1在級別列中存儲層次結構。

TAB1 
----- ----- ---- ---- 
KEY L1  L2 L3 
---- ----- ----- ---- 
A  A 
B  A  B 
C  A  B  C 
D  A  B  D 

TAB2 
----- 
KEY TC 
---- ---- 
A  10 
B  11 
C  6 
D  12 
X  11 

Expected Output: 

KEY SUM 
---- ---- 
A 39 
B 29 
C 6 
D 12 
X 11 

這裏是SQLFiddle鏈接:LINK TO FIDDLE

+0

這裏是一個偉大的地方開始。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+0

請爲此數據提供所需的輸出,因爲它不清楚什麼你的意思是*每個級別的總和*。我想至少有3種解釋。 – trincot

+0

添加到trincot的評論 - 不要只提供所需的輸出,用英文解釋(無代碼!)如何輸出。 – mathguy

回答

1

甲骨文設置

Create table TAB1 (pKey varchar2(10),level1 varchar2(10),level2 varchar2(10),level3 varchar2(10),level4 varchar2(10)); 
insert into TAB1(pKey,level1) values('A','A'); 
insert into TAB1(pKey,level1,level2) values('B','A','B'); 
insert into TAB1(pKey,level1,level2,level3) values('C','A','B','C'); 
insert into TAB1(pKey,level1,level2,level3) values('D','A','B','D'); 

Create table TAB2 (pKey varchar(10), tc integer); 
insert into TAB2(pKey,tc) values('A',10); 
insert into TAB2(pKey,tc) values('B',11); 
insert into TAB2(pKey,tc) values('C',6); 
insert into TAB2(pKey,tc) values('D',12); 
insert into TAB2(pKey,tc) values('X',11); 

查詢

SELECT t2.pKey, 
     SUM(COALESCE(t4.TC, t2.tc)) AS tc 
FROM tab2 t2 
     LEFT OUTER JOIN 
     tab1 t1 
     ON (t2.pKey = t1.pKey) 
     LEFT OUTER JOIN 
     tab1 t3 
     ON ( t1.level1 = t3.level1 
      AND (t1.level2 IS NULL OR t1.level2 = t3.level2) 
      AND (t1.level3 IS NULL OR t1.level3 = t3.level3) 
      AND (t1.level4 IS NULL OR t1.level4 = t3.level4)) 
     LEFT OUTER JOIN 
     tab2 t4 
     ON (t3.pKey = t4.pKey) 
GROUP BY t2.pKey; 

輸出

PKEY    TC 
---------- ---------- 
D     12 
A     39 
B     29 
C     6 
X     11 
1

在下面提供的解決方案(包括輸入數據作爲因式分解的子查詢),第一我展示如何使用unpivot和附加操作正常化tab1(結果是因子分解子查詢n爲「n ormalized」 )。然後,如果你有正常形式的數據,則可以通過直接應用我的代碼底部顯示的標準分層查詢來獲得輸出結果。

with 
    tab1 (key, L1, L2, L3) as (
     select 'A', 'A', null, null from dual union all 
     select 'B', 'A', 'B' , null from dual union all 
     select 'C', 'A', 'B' , 'C' from dual union all 
     select 'D', 'A', 'B' , 'D' from dual 
    ), 
    tab2 (key, TC) as (
     select 'A', 10 from dual union all 
     select 'B', 11 from dual union all 
     select 'C', 6 from dual union all 
     select 'D', 12 from dual union all 
     select 'X', 11 from dual 
    ), 
    unpiv (key, l, ancestor) as (
     select key, to_number(substr(lv, 2)), ancestor from tab1 
     unpivot (ancestor for lv in (L1, L2, L3)) 
    ), 
    d (key, depth) as (
     select key, max(l) 
     from unpiv 
     group by key 
    ), 
    n (child, parent, TC) as (
     select d.key, u.ancestor, tab2.TC 
     from unpiv u 
      right outer join d 
       on u.key = d.key and u.l = d.depth - 1 
      left outer join tab2 
       on d.key = tab2.key 
    ) 
SELECT key, sum(TC) as sum_TC 
from (
    select connect_by_root child as key, TC 
    from n 
    connect by prior child = parent 
) 
group by key 
order by key; 

一路上,在unpiv,我已經把所有的父子關係,所以我可以直接加入與tab2unpiv.key = tab2.keyancestor(類似於MT0的解決方案)總結TC分組。相反,我想演示兩個單獨的步驟:(1)規範化tab1和(2)在規範化表上使用分層查詢是多麼容易。

輸出

KEY  SUM_TC 
--- ---------- 
A   39 
B   29 
C   6 
D   12 
相關問題