将金额相加,然后在第二行在Oracle中重复时将其删除

时间:2018-11-21 10:05:40

标签: database oracle duplicates

我正在为此表做以下两件事。

enter image description here

  1. 如果按EMP_Id,Year和Type进行检查,则存在3个唯一行。我仅在重复时才需要添加Bonus_Amt的总和。例如, 对于EMP_ID = 1708301,Bonus_AMT应为= 22196 + 3036。 对于EMP_ID = 642416,它不应该做任何事情。

  2. 完成总和后,请删除第二行,但要仔细检查Bonus_Amt是否应小于重复记录中的其他行。

执行步骤1和步骤2时,表记录应如下所示。

enter image description here

我确实对点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。

2 个答案:

答案 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;

Demo DBFiddle

这可以通过查找每个组的bonus_amt的总和(与该组是一行还是多行无关),并标识组中的第一行(即,bonus_amt最高的那一行),所以我们知道要保留哪一行。

然后,我们在合并语句中使用该数据源集更新每行的bonus_amt(您需要更新每行,否则删除操作将“看到”未更新的行),然后再删除所有行但每组的第一行。

答案 1 :(得分:0)

我喜欢merge语句的答案; 只是想提出更透明的解决方案:

  1. 开始
  2. 选择按英国分组的总和(如该合并语句中所示),然后将结果插入辅助表中。 -每个英国您将有一个记录
  3. 从基表中删除所有记录
  4. 从aux .table插入基本表
  5. 提交工作;