使用子查询中的数据时如何更新插入 (Postgres)

Ada*_*uze 3 sql postgresql upsert subquery

我有两张桌子:

\n\n
    \n
  • assignments {recceptacleId, assignedCarrier}
  • \n
  • rls_permissions {receptacleId, rlsUserId}
  • \n
\n\n

此上下文中的分配是与航空公司关系的任何容器。

\n\n

每当表中出现新分配时assignments,我都想更新插入(如果是新行则插入,或者如果是分配给新航空公司的现有容器则更新)我的rls_permissions表。

\n\n

我在upsert方面遇到的问题,特别是ON CONFLICT ON CONSTRAINT,是我的插入语句包含要插入的数据的子查询,因此我不知道如何编写DO UPDATE SET部分陈述

\n\n

我尝试使用“排除”来尝试根据之前的冲突挑选出我想要更新的分配载体,但是我不断收到“错误:列排除。receptacleId 不存在”

\n\n

我的 pkey 看起来像这样:

\n\n
CREATE UNIQUE INDEX rls_permissions_pkey ON rls_permissions("receptacleId" text_ops);\n
Run Code Online (Sandbox Code Playgroud)\n\n

虚拟数据可以是:

\n\n
CREATE UNIQUE INDEX rls_permissions_pkey ON rls_permissions("receptacleId" text_ops);\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中 AA 是“美国航空”

\n\n
receptacleID    assignedCarrier\naaaaaaaaaa00    AA               \n
Run Code Online (Sandbox Code Playgroud)\n\n

例外的结果是,如果没有冲突,则将从子查询返回的数据插入到权限表的新行中。

\n\n

如果存在冲突,我只想更新新分配的运营商,而不是更新或插入新行,因为该插座已经存在。

\n

小智 5

您不需要在 UPDATE 部分中使用子查询。您可以通过关键字访问 INSERT 部分的值excluded

INSERT INTO rls_permissions ("receptacleId","rlsUserId") 
SELECT DISTINCT assignments."receptacleId", assignments."assignedCarrier" 
FROM assignments
ON CONFLICT ON CONSTRAINT rls_permissions_pkey
DO UPDATE SET "rlsUserId" = excluded."rlsUserId";
Run Code Online (Sandbox Code Playgroud)

对 的引用excluded."rlsUserId"是指已插入到 rlsUserId 列中的值,因此它是通过assignments."assignedCarrier"SELECT 语句检索到的值。