下面有两个表格
表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查询更新
答案 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中的原始数据集派生结果以更新table1
和table2
,因此在更新table1之前更容易更新table2
。
这可以通过查找table1中每组id
的最低pid
,并检查每个pid
是否有多个活动行(不需要)如果我们最多有一个活动行,则进行任何更新。
获得该信息之后,我们可以使用它来确定每个表中要更新的行,我们可以使用min_id
更新table2
,我们可以更新table1中的任何行id
与min_id
不匹配的地方。
N.B。如果您的数据中可能混合使用Y
和N
s,则可能需要跳过第二个合并语句中的and id != min_id
检查并修改更新部分以更新行如果Y
是id
,则转至min_id
,否则将其设为N
。