假设我在 Postgres 中有一个名为 t
的表:
id | group_name | state
-----------------------------
1 | group1 | 0
2 | group1 | 0
3 | group1 | 0
我需要通过 ID 更新行的 state
,同时还返回一些东西:
- 旧状态
- 同一组中
state
= 0 的剩余行数
我有一个查询来执行此操作,如下所示:
UPDATE t AS updated SET state = 1
FROM t as original
WHERE
updated.id = original.id AND
updated.id = :some_id
RETURNING
updated.state AS new_state,
original.state AS old_state,
(
SELECT COUNT(*) FROM t
WHERE
group_name = updated.group_name AND
state = 0
) as remaining_count;
但是,RETURNING
中的子查询似乎是在更新完成之前执行的,给我留下了一个 remaining_count
1.
此外,我不确定运行并发查询时它的行为如何。如果我们同时更新其中两行,它们是否有可能返回相同的 remaining_count
?
有没有更优雅的解决方案?也许是某种窗口/聚合函数?
最佳答案
子查询确实在没有看到 UPDATE
的更改的情况下运行,因为它在 UPDATE
提交之前运行,因此它是不可见的。不过,这是一个简单的解决方法;只需添加一个 where 子句来过滤掉您刚刚在子查询中更新的 ID,使您的查询如下所示:
UPDATE t AS updated SET state = 1
FROM t as original
WHERE
updated.id = original.id AND
updated.id = :some_id
RETURNING
updated.state AS new_state,
original.state AS old_state,
(
SELECT COUNT(*) FROM t
WHERE
group_name = updated.group_name AND
state = 0 AND
t.id <> :some_id /* this is what I changed */
) as remaining_count;
并发方面,我不确定行为会是什么,TBH;我能做的就是把你指向 relevant docs .
关于sql - PostgreSQL 更新并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53235773/