在 postgres 中使用 CTE 更新插入

Upsert using CTE in postgres

我需要使用来自 python 的 with ins 语句来更新我的对 table。我收到错误:psycopg2.errors.UndefinedTable: missing FROM-clause entry for table "ins" LINE 1: ... pairs_dup_key DO UPDATE SET exchange_pair_symbol=ins.exchan...

这是我的 sql 代码 运行

WITH ins (a, b, c) AS
        (VALUES ('sdf',2,3))
        INSERT INTO pairs
        (foo_id,v,w)
        SELECT foo.id, ins.b, ins.c
        FROM
        ins
        LEFT JOIN foo ON foo.name=ins.a
        ON CONFLICT ON CONSTRAINT pairs_key DO UPDATE SET v=ins.b, w=ins.c;

我做错了什么?

您的 upsert 中缺少 EXCLUDED 变量。

请记住,在冲突之后,ins.ains.b 的值不再指向它们的来源,而是指向第一次尝试将它们插入 table pairsvw 列中。因此,如果您想要访问这些值,您必须查看 EXCLUDED,而不是返回到前一个 SELECT 语句中的列。此外,您不需要 CTE 。一个简单的 FROM (VALUES...) 就足够了,例如

INSERT INTO pairs (foo_id,v,w) 
SELECT foo.id, ins.b, ins.c 
FROM (VALUES ('sdf',2,3)) ins (a,b,c)
LEFT JOIN foo ON foo.name=ins.a
ON CONFLICT (foo_id) DO UPDATE SET v=EXCLUDED.v, w=EXCLUDED.w;

但是,如果您必须坚持 CTE,请试试这个..

WITH ins (a, b, c) AS
  (VALUES ('sdf',2,3)
)
INSERT INTO pairs (foo_id,v,w) 
SELECT foo.id, ins.b, ins.c 
FROM ins LEFT JOIN foo ON foo.name=ins.a
ON CONFLICT (foo_id) DO UPDATE SET v=EXCLUDED.v, w=EXCLUDED.w;