sql - PostgreSQL 更新并返回

标签 sql postgresql

假设我在 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/

相关文章:

sql - 计算两个表中行之间的重合次数

mysql - 在这种情况下,将外键作为主键是个好主意吗?

sql - TSQL 从 xml 值中删除制表符和换行符

sql - 将文本转换为数组 - PostgreSQL

php - Mysql数据库整理与捷克符号

mysql - NodeJs Mysql - 使用对象传递 SQL 函数(NOW())

sql - 在子查询中的 CASE 表达式中返回多个值,并在主查询中再次分隔列

python - 创建用于 Django 的 PostgreSQL 数据库

python - 在长时间的数据库扫描期间发出定期提交是否有性能损失?

ruby-on-rails - 使用 pgTAP 框架来测试 postgresql 函数是一种好方法吗?