有条件更新 Postgres JSONB 列数组值

问题描述 投票:0回答:1

我有一个基本的 Postgres 表结构:

CREATE TABLE PROPS(id integer, data jsonb);

数据栏及格式:

[
  {
    "name": "abc",
    "refKey": 123
  },
  {
    "name": "cba",
    "refKey": 124
  },
  {
    "name": "xyz",
    "refKey": 123
  }  
]

我正在努力编写一条sql来将所有数据(整个PROPS表)的“refKey”从123更新到125。

postgresql sql-update jsonb
1个回答
0
投票

这是一个可以做到这一点的查询:

WITH src AS (
    SELECT id, json_array_elements(data::JSON) as arr FROM Props   
), modified AS (
    SELECT id, arr::JSONB || '{"refKey":125}'::JSONB AS arr FROM src
), regrouped AS (
    SELECT id, json_agg(arr) AS data FROM modified GROUP BY id
) 
UPDATE Props 
SET "data" = regrouped."data"
FROM regrouped
WHERE regrouped.id = Props."id";

这确实有点麻烦,但我发现使用中间CTE(通用表表达式)更容易显示步骤。

这是我们按顺序执行的操作:

  1. 在第一个 CTE 中,我扩展了 JSON 数组元素,以便我们可以使用
    json_array_elements()
    函数
    单独修改每个元素。
  2. 在第二个 CTE 中,我修改数组中的每个元素,将 refKey 更新为 125(我使用 json 连接 -
    ||
  3. 在第三个 CTE 中,我使用
    json_agg
    函数
    将数组的所有元素重新组合到单个 JSONB 数组中。
  4. 最后,将所有这些 CTE 结合起来,我们有一个简单的 UPDATE 将该数据更新回 Props 表中。

显然,您可以自定义

WHERE
命令的
UPDATE
段以仅更新某些行,并且您可以更新
modified
CTE 中的逻辑以进行不同的更新(例如增量而不是仅设置为 125)。

© www.soinside.com 2019 - 2024. All rights reserved.