我正在尝试编写以下迁移,以删除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 }
答案 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;
关于如何在子查询中生成数组还有许多其他选项。哪一个最有效取决于您的数据配置文件,索引等。在单个语句中多次更新同一行不起作用,您需要使用数组作为输入来更新每行一次。