CTE - 使用带有upsert语句

时间:2017-07-12 15:55:44

标签: sql postgresql common-table-expression upsert postgresql-9.6

我想在以下src声明中使用INSERET ... ON CONFLICT条记录

WITH src AS (
  UPDATE t1 SET
    dt = current_timestamp
    WHERE id = 1
  RETURNING *),
pub AS (
  INSERT INTO p1 SELECT s.* FROM src s
    ON CONFLICT (id) DO UPDATE SET
      -- ???
    RETURNING *)
SELECT row_to_json(pub.*)
  FROM pub;

...但我不知道如何在不指定p1更新的每一列的情况下执行此操作。基本上t1p1是相同的,插入/更新更像是副本。

所以问题是,有没有一种很好的方法来更新p1 ON CONFLICT而不指定所有列?

1 个答案:

答案 0 :(得分:1)

简而言之:语法上不可能(至少以简单的方式)。

有一个技巧,你不需要像f1 = excluded.f1, f2 = excluded.f2那样编写对,依此类推,但只有两个相同字段列表的副本:

WITH src AS (
  UPDATE t1 SET
    dt = current_timestamp
    WHERE id = 1
  RETURNING *),
pub AS (
  INSERT INTO p1 SELECT s.* FROM src s
    ON CONFLICT (id) DO UPDATE SET
      (f1,f2,f3...) = (select f1,f2,f3... from (select excluded.*) as e)
    RETURNING *)
SELECT row_to_json(pub.*)
  FROM pub;

Example on dbfiddle