sql - 如何改进这个条件 UPDATE 查询?

标签 sql postgresql

我有一个包含几列的表t,我们将它们命名为abc。我还有一个 state 列,用于指示当前状态。还有一个 id 列。

我想编写以下查询:始终更新列a,但仅当应用程序时更新bc >state 仍然等于数据库state。这里,state 列用于乐观锁定。

我将此查询编写如下:

UPDATE t
SET    a = $a$,
       b = (CASE WHEN state = $state$ THEN $b$ ELSE b END),
       c = (CASE WHEN state = $state$ THEN $c$ ELSE c END)
WHERE  id = $id$ AND
       (
         a != $a$ OR
         b != (CASE WHEN state = $state$ THEN $b$ ELSE b END) OR
         c != (CASE WHEN state = $state$ THEN $c$ ELSE c END)
       )

这里,$id$$a$、...是来自应用程序的输入变量。 WHERE 子句的第二部分是为了避免无法有效更新任何内容的更新。

该查询按预期工作,但非常笨拙。我多次重复相同的条件。我正在寻找一种以更优雅的方式重写此查询的方法。如果这是一个简单的 SELECT 查询,我可以使用 LATERAL JOIN 执行某些操作,但我不知道如何在此处应用它。

如何改进此查询?

最佳答案

将查询分成两部分:

UPDATE t
SET    a = $a$
WHERE  id = $id$

UPDATE t
SET    b = $b$,
       c = $c$
WHERE  id = $id$ AND
       state = $state$

如果您需要原子性,请包装在事务中。

关于sql - 如何改进这个条件 UPDATE 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48823748/

相关文章:

c# - 并非所有代码路径在循环时都返回值

mySQL - 获取正在查询的分片

postgresql - 如何简单地将两列转置为postgres中的一行?

python - PYODBC 不喜欢 %, "The SQL contains 2 parameter markers, but 1 parameters were supplied."

mysql - 使用 WHERE 选择 LEFT/RIGHT JOIN 并返回 NULL

sql - 我如何重新发送所有失败的电子邮件 (msdb.dbo.sp_send_dbmail)

sql - Postgres 创建一个带有外键数组的表

database - 在给定半径内搜索相应对象位置的酒店(Gem Geocoder)

sql - 更新股票信息的 PostgreSQL 合并查询 - "MERGE"处或附近的语法错误

ruby-on-rails - 尝试通过 accepts_nested_attributes_for 查找或创建?