PostgreSQL 更新并返回

Sup*_*ron 5 sql postgresql

假设我有一个名为tPostgres 的表:

   id   | group_name | state
-----------------------------
   1    |   group1   |   0
   2    |   group1   |   0
   3    |   group1   |   0
Run Code Online (Sandbox Code Playgroud)

我需要state按 ID 更新行,同时还返回一些内容:

  • 旧状态
  • 同一组中剩余的行数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;
Run Code Online (Sandbox Code Playgroud)

然而,似乎其中的子查询是在更新完成之前RETURNING执行的,给我留下了 1 的值。remaining_count

此外,我不确定运行并发查询时它的行为如何。如果我们同时更新其中两行,它们是否有可能返回相同的结果remaining_count

有更优雅的解决方案吗?也许某种窗口/聚合函数?

Ada*_*mKG 7

子查询确实在没有看到 的更改的情况下运行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;
Run Code Online (Sandbox Code Playgroud)

就并发而言,我不确定行为会是什么,TBH;我能做的就是向您指出相关文档