2015-11-18 3 views
0

У меня есть таблица в Oracle, которая содержит:Используйте функцию SUM в оракула

id | month | payment | rev 
---------------------------- 
    A | 1 | 10  | 0 
    A | 2 | 20  | 0 
    A | 2 | 30  | 1 
    A | 3 | 40  | 0 
    A | 4 | 50  | 0 
    A | 4 | 60  | 1 
    A | 4 | 70  | 2 

Я хочу, чтобы вычислить столбец оплаты (SUM(payment)). Для (id=A month=2) и (id=A month=4), я просто хочу взять наибольшее значение от колонки REV. Так что сумма равна (10+30+40+70)=150. Как это сделать?

ответ

1

Это предполагает, что вы не имеете более одного значения за оборот. Если это не так, то вам, вероятно, нужна аналитика row_number вместо max.

with latest as (
    select 
    id, month, payment, rev, 
    max (rev) over (partition by id, month) as max_rev 
    from table1 
) 
select sum (payment) 
from latest 
where rev = max_rev 
+1

Я предпочитаю семантику этого метода row_number: «выберите номер версии, который является максимальным числом' (id, month) 'номеров ревизий». Он также может работать лучше, чем метод row_number для больших наборов данных, так как легче хранить одно максимальное значение для каждого (id, month) ', чем ранжировать все возможные номера версий. –

0

выберите сумму (платеж) из таблицыName, где id = 'A' и month = 2 OR month = 4 order by payment asc;

+2

Это не то, что хочет OP - они хотят суммировать все месяцы, но за месяцы с более чем одной строкой - только максимальное значение. –

+0

Я тоже не думаю, что компилирует ... || в Oracle является concatenate – Hambone

+0

Извините, я понимаю свою ошибку, что в oracle мы используем OR not || – Ghayel

2

Вы также можете использовать ниже.

select id,sum(payment) as value 
    from 
    (
    select id,month,max(payment) from table1 
    group by id,month 
    ) 
    group by id 

Edit: для проверки наибольшего значения оборотов

select id,sum(payment) as value 
from (
select id,month,rev,payment ,row_number() over (partition by id,month order by rev desc) as rno  from table1 
) where rno=1 
group by id 
+0

. Я думаю, что проблема с этим заключается в том, что если максимальный платеж находится на чем-то отличном от последней версии, это не сработает. Например, если ревизия 1 месяца 4 составляла 100, вы выбрали бы эту запись вместо ревизии 2 – Hambone

+0

@Hambone Спасибо за то, что она была замечена, теперь я обновил свой запрос, пожалуйста, проверьте его. – Buddi

+1

Да, если я не понял вопрос, я думаю, что второй прибил его – Hambone

0

Или есть это, если я понял право требования:

with demo as (
    select 'A'as id, 1 as month, 10 as payment, 0 as rev from dual 
    union all select 'A',2,20,0 from dual 
    union all select 'A',2,30,1 from dual 
    union all select 'A',3,40,0 from dual 
    union all select 'A',4,50,0 from dual 
    union all select 'A',4,60,1 from dual 
    union all select 'A',4,70,2 from dual 
) 
select sum(payment) keep (dense_rank last order by rev) 
from demo; 

Вы можете проверить разбивку путем включения ключа колонны:

with demo as (
    select 'A'as id, 1 as month, 10 as payment, 0 as rev from dual 
    union all select 'A',2,20,0 from dual 
    union all select 'A',2,30,1 from dual 
    union all select 'A',3,40,0 from dual 
    union all select 'A',4,50,0 from dual 
    union all select 'A',4,60,1 from dual 
    union all select 'A',4,70,2 from dual 
) 
select id, month, max(rev) 
    , sum(payment) keep (dense_rank last order by rev) 
from demo 
group by id, month; 
Смежные вопросы