postgres-如何在合并的更新查询中两次更新同一记录

时间:2019-03-26 13:19:33

标签: sql postgresql

我正在尝试编写以下迁移,以删除conversations_users表(这是一个包含read_up_to列的联接表)并将read_up_to信息复制到新的{ {1}}数组。对于每1条消息行,至少有2条sessions_users行,因此此联接重复了消息。我希望下面的表达式可以工作,但是它只是将一个messages.read_by_user_ids分配给user_id数组,而且我猜这是因为更新不是按顺序进行的。

结果: read_by_user_ids

期望的结果:message_id: 1, read_by_user_ids: { 15 }

message_id: 1, read_by_user_ids: { 15, 19 }

1 个答案:

答案 0 :(得分:1)

我在打电话,所以对未经测试的错字表示歉意。

根据我的评论,每个会话将单个传入的user_id聚集到一个数组中。然后使用array_cat合并两个数组。

这样,您只需要对每个目标行进行一次更新即可。

我还注意到您只想基于日期比较来更新行,因此我将其添加到了我建议的子查询中。

UPDATE
  messages as m
SET
  read_by_user_ids = array_cat(
      COALESCE(m.read_by_user_ids, '{}'),
      cu.user_id_array
    )
FROM
(
  SELECT
    cu.conversation_id,
    array_agg(cu.user_id)   AS user_id_array
  FROM
    messages
  INNER JOIN
    conversations_users
      ON  cu.conversation_id  = m.thread_id
      AND cu.read_up_to      >= m.created_at
  GROUP BY
    cu.conversation_id
)
  cu
WHERE
  cu.conversation_id = m.thread_id;

关于如何在子查询中生成数组还有许多其他选项。哪一个最有效取决于您的数据配置文件,索引等。在单个语句中多次更新同一行不起作用,您需要使用数组作为输入来更新每行一次。