停用重复记录并将子记录重新指向活动记录

时间:2018-01-24 13:25:40

标签: oracle

下面有两个表格

表1

ID Name Age Active PID
-----------------------------
1   A    2   Y     100
2   A    2   Y     100
3   A    2   Y     100
4   B    3   Y     200
5   B    3   Y     200

表2

T2ID CID  
---------
10    1    
20    1    
30    1    
40    2    
50    2    
60    3
70    3
80    3
90    4
100   5
110   5

我试图取消激活表1的重复记录,并将table2记录重新分配给表1的激活行,table1和table2的结果应如下所示

ID Name Age Active PID
-----------------------------
1   A    2   Y     100
2   A    2   N     100
3   A    2   N     100
4   B    3   N     200
5   B    3   Y     200

T2ID CID  
---------
10    1    
20    1    
30    1    
40    1    
50    1    
60    1
70    1
80    1
90    5
100   5
110   5

请帮助oracle查询更新

1 个答案:

答案 0 :(得分:1)

您可以使用两个合并语句来执行此操作,如下所示:

更新table2:

MERGE INTO table2 tgt
  USING (WITH t1 AS (SELECT ID,
                            NAME,
                            age,
                            active,
                            pid,
                            MIN(ID) OVER (PARTITION BY pid) min_id,
                            CASE WHEN COUNT(CASE WHEN active = 'Y' THEN 1 END) OVER (PARTITION BY pid) > 1 THEN 'Y' ELSE 'N' END multi_active_rows
                     FROM   table1)
         SELECT t2.t2id,
                t2.cid old_cid,
                t1.min_id new_cid
         FROM   t1
                INNER JOIN table2 t2 ON t1.id = t2.cid
         WHERE  t1.multi_active_rows = 'Y') src
    ON (tgt.t2id = src.t2id)
WHEN MATCHED THEN
  UPDATE SET tgt.cid = src.new_cid;

更新table1:

MERGE INTO table1 tgt
  USING (WITH t1 AS (SELECT ID,
                            NAME,
                            age,
                            active,
                            pid,
                            MIN(ID) OVER (PARTITION BY pid) min_id,
                            CASE WHEN COUNT(CASE WHEN active = 'Y' THEN 1 END) OVER (PARTITION BY pid) > 1 THEN 'Y' ELSE 'N' END multi_active_rows
                     FROM   table1)
         SELECT ID
         FROM   t1
         WHERE  multi_active_rows = 'Y'
         AND    ID != min_id) src
    ON (tgt.id = src.id)
WHEN MATCHED THEN
  UPDATE SET active = 'N';

由于我们希望从table1中的原始数据集派生结果以更新table1table2,因此在更新table1之前更容易更新table2

这可以通过查找table1中每组id的最低pid,并检查每个pid是否有多个活动行(不需要)如果我们最多有一个活动行,则进行任何更新。

获得该信息之后,我们可以使用它来确定每个表中要更新的行,我们可以使用min_id更新table2,我们可以更新table1中的任何行idmin_id不匹配的地方。

N.B。如果您的数据中可能混合使用YN s,则可能需要跳过第二个合并语句中的and id != min_id检查并修改更新部分以更新行如果Yid,则转至min_id,否则将其设为N