2016-09-21 88 views
0

我真的很困惑自我加入的工作方式,只有几个自我加盟的例子,主要是它显示了如何知道在一个表中的雇员经理。所以我有这个表有人可以向我解释自我加入如何工作

ItemCode  ItemNo ItemTotal 
--------------------------------- 
CT1  | A  | 20 
CT1  | A  | 30 
CT2  | A  | 40 
CT2  | A  | 10 

我想每ItemCodeItemNoSum()ItemTotal和使用Sum()ItemNoItemCodeItemtotal将其分摊。例如,在ItemCode CT1和ItemNoA它的总和是50,并且希望通过20和30,它是原始itemTotalItemCode CT1和ItemNo答同样会发生到下一不同ItemCodeItemNo来划分它。此外,如果你可以提供一个有用的解释。干杯!

预期结果

ItemCode  ItemNo  ItemTotal 
------------------------------------- 
CT1  |  A  | 0.4 ----20/50 
CT1  |  A  | 0.6 ----30/50 
CT2  |  A  | 0.8 
CT2  |  A  | 0.2 
+0

显示我们预期的结果,格式化的方式为您的样本数据相同。 – jarlh

+0

@jarlh编辑!我缩短了表格并添加了我的预期结果 –

+3

这个问题的问题在于,标题和开头词语预先假定自联接是问题解决方案的必需部分。一旦实际描述问题,很明显自联接可能不相关。 –

回答

3

您可以用单一扫描做你的表:

with test(ItemCode, ItemNo, ItemTotal) as 
(
    select 'CT1', 'A', 20 from dual union all 
    select 'CT1', 'A', 30 from dual union all 
    select 'CT2', 'A', 40 from dual union all 
    select 'CT2', 'A', 10 from dual 
) 
select ItemCode, ItemNo, 
     ItemTotal/sum(ItemTotal) over (partition by ItemCode,ItemNo) 
from test 

为了完整起见,如果你想与一个加入一个解决方案,你可以使用:

select ItemCode,ItemNo, t1.ItemTotal/sum(t2.ItemTotal) 
from test t1 
    inner join test t2 
     using(ItemCode,ItemNo) 
group by ItemCode, ItemNo, t1.ItemTotal 

然而这两种方法有不同的表现;对于加盟的解决方案计划:

---------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  8 | 336 |  8 (25)| 00:00:01 | 
| 1 | HASH GROUP BY  |  |  8 | 336 |  8 (25)| 00:00:01 | 
|* 2 | HASH JOIN   |  |  8 | 336 |  7 (15)| 00:00:01 | 
| 3 | TABLE ACCESS FULL| TEST |  4 | 84 |  3 (0)| 00:00:01 | 
| 4 | TABLE ACCESS FULL| TEST |  4 | 84 |  3 (0)| 00:00:01 | 
---------------------------------------------------------------------------- 

,为单次扫描解决方案:

--------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  4 | 84 |  4 (25)| 00:00:01 | 
| 1 | WINDOW SORT  |  |  4 | 84 |  4 (25)| 00:00:01 | 
| 2 | TABLE ACCESS FULL| TEST |  4 | 84 |  3 (0)| 00:00:01 | 
--------------------------------------------------------------------------- 
+0

这就是我的意思! – jarlh

+0

@Aleksej再次感谢哈哈! –

1

甲骨文可能有一些花哨的功能做到这一点。但因为我不知道甲骨文说好了,我会做一个简单的相关子查询答案:

select 
    ItemCode, 
    ItemNo, 
    ItemTotal * 1.0/(
     select SUM(ItemTotal) 
     from tablename t2 
     where t2.ItemNo = t1.ItemNo 
    ) 
from tablename t1 

也许你想要做

cast(ItemTotal * 1.0/(
    select SUM(ItemTotal) 
    from tablename t2 
    where t2.ItemNo = t1.ItemNo 
) as decimal(1,1)) 
+1

我添加了Oracle花哨功能方法作为答案。 –

1

这里是这样做的甲骨文花哨功能的方法:

select ItemCode, 
     ItemNo, 
     ratio_to_report(ItemTotal) over (partition by ItemCode,ItemNo) 
from my_table; 

注意,这可以说是比以下更强健:

ItemTotal/sum(ItemTotal) over (partition by ItemCode,ItemNo) 

...因为它隐含零个错误陷阱师并返回null,否则将需要:

ItemTotal/NullIf(sum(ItemTotal) over (partition by ItemCode,ItemNo) , 0) 
相关问题