使用 CASE 在 UPDATE 查询中选择列?

new*_*der 16 postgresql update

我可以CASE用来选择在SELECT查询 (Postgres) 中显示哪些列,如下所示:

SELECT CASE WHEN val = 0 THEN column_x
            WHEN val = 1 THEN column_y
            ELSE 0
       END AS update, ...
Run Code Online (Sandbox Code Playgroud)

UPDATE在 Postgres 中执行查询时是否有可能发生类似的事情(即选择应该更新哪些列)?我假设不是,因为我找不到任何关于此的信息,但也许有人有一个聪明的选择(除了使用过程或使用 a 更新每一列CASE来确定是否应为该列的值分配一个新值或简单地重新分配现有的价值)。如果没有简单的选择,我当然也会接受它作为答案。

额外信息:在我的情况下,我有 14 个可能的列可以更新,每个匹配行只更新一个(要更新的表与查询中的另一个表连接)。要更新的行数很可能会有所不同,可能是数十或数百。我相信加入条件的索引已经到位。

Dav*_*ett 31

如果您指定应更新列,则它将始终更新,您可以有条件地更改您输入的值,并根据您的条件放回原始值。就像是:

UPDATE some_table
SET    column_x = CASE WHEN should_update_x THEN new_value_for_x ELSE column_x END
     , column_y = CASE WHEN should_update_y THEN new_value_for_y ELSE column_y END
     , column_z = CASE WHEN should_update_z THEN new_value_for_z ELSE column_z END
FROM   ...
Run Code Online (Sandbox Code Playgroud)

因此,如果条件不适合更新特定列,您只需反馈它的当前值。

请注意,匹配的每一行都会看到更新(即使所有列最终都设置为它们已经拥有的值),除非您在过滤 ON 和 WHERE 子句时明确地排除这种情况,这可能是一个性能问题(会有写入,索引将被更新,适当的触发器将被触发,...)如果没有缓解。


Col*_*art 5

您有多少种不同的列组合需要更新?整个表会更新多少行?是否有索引可以快速访问要更新的行?

根据这些问题的答案,您可能能够执行多个更新语句,针对您希望更新的每一列执行一个,并将条件放在更新的 where 子句中该列的值上,以便在该列时更新​​零行有错误的价值。

尝试考虑基于集合,不要假设更新需要更新主键找到的单行。