2016-09-21 3 views
0

im действительно озадачен тем, как работает самообслуживание, и есть только несколько примеров самоубийств в Интернете, и в основном это просто показывает, как знать менеджера сотрудника в таблице. Таким образом, у меня есть эта таблицаМожет ли кто-нибудь объяснить мне, как работать самостоятельно?

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

Я хотел бы Sum() колонку ItemTotal за ItemCode и ItemNo и использовать Sum(), чтобы разделить его на оригинальный Itemtotal на ItemNo и ItemCode. Например, в ItemCode СТ1 и ItemNoA сумма его составляет 50 и хотел бы разделить его на 20 и 30, который является оригинальным itemTotal для ItemCode СТ1 и ItemNo А. То же самое произойдет в следующий иной ItemCode и ItemNo. Также, если вы можете предоставить объяснение, которое было бы полезно. Ура!

Ожидаемый результат

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

Oracle, вероятно, имеет некоторые фантазии функциональность, чтобы сделать это. Но так как я не знаю Oracle, что хорошо, я сделаю простой коррелированных ответ суб-запроса:

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

Вот Oracle фантазии функциональность способ сделать это:

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

Обратите внимание, что это, возможно, более прочные, чем:

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

... как это неявно улавливает деление на ноль ошибок и возвращает нуль, которые в противном случае потребуется:

ItemTotal/NullIf(sum(ItemTotal) over (partition by ItemCode,ItemNo) , 0) 
Смежные вопросы