PostgreSQL 无法使用 "WITH" 进行 UPSERT

PostgreSQL can't UPSERT with a "WITH"

我想用 WITH 插入一个值,如下所示:

WITH counted as (
   SELECT votant, count(*) as nbvotes
    FROM votes
    WHERE votant = '123456'
    GROUP BY votant
)

INSERT INTO badges(id, badge, conditions, niveau, date_obtention)
VALUES('123456', 'category', c.nbvotes, 1, current_timestamp)
ON CONFLICT (id, badge)
DO UPDATE badges b
SET b.conditions = c.nbvotes
FROM counted c
WHERE b.id = c.votant AND b.badge = 'category'

控制台告诉我在“DO UPDATE”之后的“badges”出现错误 我真的不明白这里出了什么问题,如果任何 bpdy 可以帮助我,那就太好了:)

As documented in the manual do update 部分之后的 badges b 是错误的 - 如果您认为它是不必要的。目标 table 已由 INSERT 部分定义。

但您也不需要 FROM 或加入原始值。

所以只需使用:

...
ON CONFLICT (id, badge)
DO UPDATE 
  SET conditions = '{"a":"loooool"}';

如果需要访问原始值,可以使用excluded记录来引用它,例如

  SET conditions = EXCLUDED.conditions

在您的情况下,它指的是 values 子句中提供的行(在您的示例中为 {"a":"lol"}'

并且 UPDATE 的目标列不能是 table 限定的。所以只是 SET conditions = ...


如果要将 CTE 的结果用作 INSERT 的源,则需要使用 INSERT ... SELECT。不能在 INSERT 的 DO UPDATE 部分使用 FROM 子句。

WITH counted as (
  SELECT votant, count(*) as nbvotes
  FROM votes
  WHERE votant = '123456'
  GROUP BY votant
)
INSERT INTO badges(id, badge, conditions, niveau, date_obtention)
SELECT '123456', 'category', c.nbvotes, 1, current_timestamp
FROM counted c
ON CONFLICT (id, badge)
DO UPDATE 
   SET conditions = excluded.conditions