使用WITH子句将Oracle Merge迁移到Postgres时遇到问题。
以下是ORACLE的示例代码:
SELECT * FROM source;
ID STATUS DESCRIPTION
---------- ---------- -----------------------
1 20 Description of level 1
2 10 Description of level 2
3 20 Description of level 3
4 10 Description of level 4
5 20 Description of level 5
目的地表如下:
SELECT * FROM destination;
1 20 Description of level 1
2 10 Description of level 2
3 20 Description of level 3
4 10 Description of level 4
5 20 Description of level 5
6 10 Description of level 6
7 20 Description of level 7
8 10 Description of level 8
9 20 Description of level 9
10 10 Description of level 10
我在ORACLE中有Merge实现,如下所示:合并时:
MERGE INTO destination d
USING source s
ON (s.id = d.id)
WHEN MATCHED THEN
UPDATE SET d.description = 'Updated'
DELETE WHERE d.status = 10;
5 rows merged.
SELECT * FROM destination;
ID STATUS DESCRIPTION
---------- ---------- -----------------------
1 20 Updated
3 20 Updated
5 20 Updated
6 10 Description of level 6
7 20 Description of level 7
8 10 Description of level 8
9 20 Description of level 9
10 10 Description of level 10
8 rows selected.
我能够转换一个在MATCHED和MAT中都有一个条件的Merge。使用CTE的UNMATCHED条款。 但是如果我在同一条款中有两个条件,则不确定如何做(DELETE和UPDATE)。
编辑: 我理解a_horse_with_no_name已经共享的答案。但是在下面的情况下我是否需要做嵌套的CTE感到困惑。
MERGE INTO destination d
USING source s
ON (s.id = d.id)
WHEN MATCHED THEN
UPDATE SET d.description = 'Updated'
DELETE WHERE d.status = 10
WHEN NOT MATCHED THEN
INSERT (ID, STATUS, DESCRIPTION) VALUES (s.id,s.status,s.description);
如果我的合并声明也没有匹配,那我该怎么办呢。
答案 0 :(得分:0)
我不确定这是否是最有效的方法,但它可以满足您的需求:
with updated as (
update destination d
set description = 'Updated'
from source s
where s.id = d.id
and d.status <> 10
returning d.id
)
delete from destination
where id not in (select id from updated)
and exists (select *
from source s
where s.id = destination.id);
它首先更新destination
中存在于source
中且状态不是10的行。然后删除那些未更新并存在于source
表中的行。