Вы можете сделать это с помощью слияния. С фиктивной таблицей для моделирования ваших данных:
create table t42 (identifier varchar2(10), revenue number, good_inflow number);
insert into t42 values ('abc123', 20, 15);
insert into t42 values ('abc124', 10, 5);
insert into t42 values ('abc124', 5, 5);
вы можете использовать аналитические функции, чтобы получить в общей сложности в качестве дополнительного столбца с каждой строкой, а также ряд псевдо строк:
select t42.*,
sum(revenue) over (partition by identifier, good_inflow) as total_revenue,
row_number() over (partition by identifier, good_inflow order by rowid) as rn,
count(*) over (partition by identifier, good_inflow) as cnt
from t42;
IDENTIFIER REVENUE GOOD_INFLOW TOTAL_REVENUE RN CNT
---------- ------- ----------- ------------- ---- ----
abc123 20 15 20 1 1
abc124 10 5 15 1 2
abc124 5 5 15 2 2
Вы можете затем используйте это как предложение using
инструкции merge
, добавив rowid
базовой таблицы в качестве условия on
и используя сгенерированный cnt
только для обновления тех, у которых есть дубликаты (так что любая пара ID/притока, которая появляется только один раз, не бесцельно обновляется до той же стоимости е):
merge into (select t42.*, rowid from t42) t42
using (
select t42.*, rowid,
sum(revenue) over (partition by identifier, good_inflow) as total_revenue,
row_number() over (partition by identifier, good_inflow order by rowid) as rn,
count(*) over (partition by identifier, good_inflow) as cnt
from t42
) tmp
on (tmp.rowid = t42.rowid and tmp.cnt > 1)
when matched then
update set revenue = case when tmp.rn = 1 then tmp.total_revenue else null end
delete where (revenue is null);
2 rows merged.
delete
Предложение работ по значению после обновления; Я использовал выражение case для того, чтобы установить доход в null для всех, кроме номинальной первой строки для каждой комбинации. Теперь они могут быть удалены.
select * from t42;
IDENTIFIER REVENUE GOOD_INFLOW
---------- ------- -----------
abc123 20 15
abc124 15 5
Однако это не означает, что значение дохода не может быть равно нулю. Если он имеет значение NULL, он может быть адаптирован для решения этой проблемы.
Пожалуйста, покажите свои данные в виде отформатированного текста, а не изображения. Это только три столбца в вашем столе? Вам нужно только объединить эту конкретную пару строк (что вы можете сделать с простым обновлением и удалить с использованием определенного значения), или у вас есть много одинаковых пар, которые нужно объединить? –
Вы хотите, чтобы это было как запрос SELECT, так и как оператор удаления? – kbball
@AlexPoole - Вопрос в том, действительно ли это требование (изменить данные в таблице, а не просто группировать данные для отчета) - это хорошая практика? На мой взгляд, в большинстве случаев это плохая практика. Можно писать представления (и MVs, если это необходимо для производительности) для целей анализа и отчетности, но базовые данные следует оставить в покое. – mathguy