在 Postgres 的相同 CLAUSE 选项中合并具有两个条件的语句

Merge statement with two conditions in same CLAUSE alternative in Postgres

我在使用 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

目的地 table 如下:

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.

我能够使用 CTE 转换在 MATCHED 和 UNMATCHED 子句中都具有一个条件的 Merge。 但不确定如何做(删除和更新),如果我在同一个子句中有两个条件。

已编辑: 我了解 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);

如果我的合并语句也不匹配,那我该怎么做。

我不确定这是否是最有效的方法,但它可以满足您的要求:

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 中的行 table.

在线示例:http://rextester.com/KTTOX89581