【问题标题】:How to upsert when using data from a sub-query (Postgres)使用子查询中的数据时如何更新插入(Postgres)
【发布时间】:2020-02-04 03:50:51
【问题描述】:

我有两张桌子:

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

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

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

我遇到的 upsert 问题,特别是 ON CONFLICT ON CONSTRAINT,是我的插入语句包含要插入的数据的子查询,因此我不确定如何编写 DO UPDATE SET 部分声明

我已经尝试使用“排除”来尝试根据之前的冲突挑选出我想要更新的assignedCarrier,但是我一直收到“错误:列excluded.receptacleId 不存在”

我的 pkey 如下所示:

CREATE UNIQUE INDEX rls_permissions_pkey ON rls_permissions("receptacleId" text_ops);

虚拟数据可能是:

receptacleID    assignedCarrier
aaaaaaaaaa00    AA               

AA 是“美国航空公司”

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" = (SELECT DISTINCT assignments."assignedCarrier" 
                             FROM assignments 
                             WHERE assignments."receptacleId" = excluded."receptacleId");

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

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

【问题讨论】:

  • 你真的应该避免那些可怕的引用标识符。从长远来看,它们带来的麻烦远多于它们的价值。 wiki.postgresql.org/wiki/…

标签: sql postgresql subquery upsert


【解决方案1】:

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

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";

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

【讨论】:

  • 非常感谢!我误解了排除的工作原理。
猜你喜欢
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-06
相关资源
最近更新 更多