【问题标题】:Merge statement with two conditions in same CLAUSE alternative in Postgres在 Postgres 的相同 CLAUSE 替代项中合并具有两个条件的语句
【发布时间】:2018-02-07 19:30:55
【问题描述】:

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

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

【问题讨论】:

    标签: sql postgresql common-table-expression postgresql-9.4


    【解决方案1】:

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

    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 表中的行。

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

    【讨论】:

    • 如果我们与两个 DML 语句匹配但与一个或多个 DML 语句不匹配,请告诉我如何使用 CTE 子句转换为 Postgres 代码。
    猜你喜欢
    • 2022-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 2019-09-19
    • 2020-09-02
    相关资源
    最近更新 更多