Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 每个级别的层次结构查询和_Sql_Oracle - Fatal编程技术网

Sql 每个级别的层次结构查询和

Sql 每个级别的层次结构查询和,sql,oracle,Sql,Oracle,我有以下表格结构。我想从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

我有以下表格结构。我想从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

这里是SQLFIDLE链接:

Oracle设置

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 
KEY     SUM_TC
--- ----------
A           39
B           29
C            6
D           12
输出

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 
KEY     SUM_TC
--- ----------
A           39
B           29
C            6
D           12

在下面提供的解决方案中(包括作为分解子查询的输入数据),首先我展示了如何使用
unpivot
和其他操作来规范化
tab1
(结果是“
n
ormalized”的分解子查询
n
)。然后,如果数据是标准形式的,那么可以通过直接应用标准分层查询来获得输出,如代码底部所示

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
中,我已经拥有了所有的父子关系,因此我可以直接将其与
unpiv.key=tab2.key
上的
tab2
连接起来,并将
TC
祖先进行分组(类似于MT0的解决方案)。相反,我想演示两个单独的步骤:(1)规范化
tab1
,以及(2)在规范化表上使用分层查询是多么容易

输出

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 
KEY     SUM_TC
--- ----------
A           39
B           29
C            6
D           12

这是一个很好的起点。请提供该数据的预期输出,因为不清楚各层级总和的含义。我想至少有3种解释。在trincot的评论中加上-不要只提供所需的输出,用英语(没有代码!)解释输出是如何派生的。哦-我想我现在明白了。在示例输入的最后一行L3列中,您的意思是写D而不是C吗?另外,您是否拥有TAB1中的数据,而不是包含“父”和“子”的规范化表(仅在两列中)?我已添加到SQL FIDLE中