我正在为此表做以下两件事。
如果按EMP_Id,Year和Type进行检查,则存在3个唯一行。我仅在重复时才需要添加Bonus_Amt的总和。例如, 对于EMP_ID = 1708301,Bonus_AMT应为= 22196 + 3036。 对于EMP_ID = 642416,它不应该做任何事情。
完成总和后,请删除第二行,但要仔细检查Bonus_Amt是否应小于重复记录中的其他行。
执行步骤1和步骤2时,表记录应如下所示。
我确实对点1尝试了以下操作,但这给了我第2行而不是第1行。如果我更改t.rn = 1,那么它将选择所有记录,即使不是重复的记录。>
SELECT t.*
FROM (SELECT o.*, ROW_NUMBER() OVER (PARTITION BY o.EMP_Id ORDER BY o.Year) rn
FROM Emp_Stat o where o.Year='2018' AND o.Type= 'Check'
) t
WHERE t.rn > 1
此处的UniqueId无关紧要。要注意的是,只有重复的记录才是总和,然后删除未添加的记录。此外,还有一列lst_update_time,该列仅应针对重复的行而不应针对任何其他记录更新为sysdate。
答案 0 :(得分:2)
您可以在单个MERGE语句中执行此操作,同时使用when matched
子句中的update和delete,如下所示:
merge into t1 tgt
using (select unique_id,
emp_id,
sum(bonus_amt) over (partition by emp_id, year, type) new_bonus_amt,
year,
type,
count(*) over (partition by emp_id, year, type) grp_count,
row_number() over (partition by emp_id, year, type order by bonus_amt desc) rn
from t1) src
on (tgt.unique_id = src.unique_id and src.grp_count > 1)
when matched then
update set tgt.bonus_amt = src.new_bonus_amt,
tgt.last_update_time = sysdate
delete where rn != 1;
这可以通过查找每个组的bonus_amt的总和(与该组是一行还是多行无关),并标识组中的第一行(即,bonus_amt最高的那一行),所以我们知道要保留哪一行。
然后,我们在合并语句中使用该数据源集更新每行的bonus_amt(您需要更新每行,否则删除操作将“看到”未更新的行),然后再删除所有行但每组的第一行。
答案 1 :(得分:0)
我喜欢merge语句的答案; 只是想提出更透明的解决方案: