You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更新PostgreSQL表中JSON数组内的每个JSON对象?

为JSON数组中的每个对象添加新字段的SQL解决方案

表结构与数据格式

table_b表结构:

id (integer)data (json)text (text)
1{}yes
2{}no

data字段的JSON格式示例:

{"types": [{"key": "first_event", "value": false}, {"key": "second_event", "value": false}, {"key": "third_event", "value": false}]}

需求

仅更新text = 'yes'的记录,为data->'types'数组中的每个JSON对象添加"can": ["test1", "test2"]字段,最终效果:

{"types": [{"key": "first_event", "value": false, "can":["test1", "test2"] }, {"key": "second_event", "value": false , "can":["test1", "test2"]}, {"key": "third_event", "value": false , "can":["test1", "test2"]}]}

原SQL失效原因

你之前使用的jsonb_set语句只能针对固定路径的单个节点修改,无法遍历数组中的所有元素批量添加字段,因此无法生效。

正确解决方案

针对jsonb类型字段的更新语句

如果data字段是jsonb类型,直接使用以下SQL:

UPDATE table_b
SET data = jsonb_set(
    data,
    '{types}',
    (
        SELECT jsonb_agg(elem || '{"can": ["test1", "test2"]}'::jsonb)
        FROM jsonb_array_elements(data->'types') AS elem
    ),
    true
)
WHERE text = 'yes';

针对json类型字段的更新语句

如果data字段是json类型,需要先转换为jsonb处理,再转回json:

UPDATE table_b
SET data = (
    jsonb_set(
        data::jsonb,
        '{types}',
        (
            SELECT jsonb_agg(elem || '{"can": ["test1", "test2"]}'::jsonb)
            FROM jsonb_array_elements(data::jsonb->'types') AS elem
        ),
        true
    )
)::json
WHERE text = 'yes';

逻辑说明

  1. jsonb_array_elements(data->'types'):将types数组拆分为单独的JSON对象行
  2. elem || '{"can": ["test1", "test2"]}'::jsonb:为每个JSON对象拼接新的can字段
  3. jsonb_agg(...):将处理后的所有对象重新聚合为一个数组
  4. jsonb_set:把新生成的types数组替换回原data字段的对应位置

内容的提问来源于stack exchange,提问作者Семен Немытов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:50:21