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

Postgres中根据ID替换jsonb数组内的指定对象

替换PostgreSQL JSONB数组中匹配ID的对象

因为你的场景中ID是唯一的,我们可以通过展开JSONB数组、替换匹配元素、重新聚合数组的方式实现需求,具体方案如下:

直接更新表的SQL语句

假设你的表名为target_table,JSONB列名为data_column,传入的新对象为new_obj(JSONB类型),执行以下UPDATE语句即可完成替换:

UPDATE target_table
SET data_column = (
  -- 展开数组后逐个判断,匹配ID则替换为新对象,否则保留原元素,最后重新聚合为数组
  SELECT jsonb_agg(
    CASE WHEN elem->>'id' = new_obj->>'id' THEN new_obj ELSE elem END
  )
  FROM jsonb_array_elements(data_column) AS elem
)
-- 仅更新存在匹配ID的行,避免无意义操作
WHERE EXISTS (
  SELECT 1
  FROM jsonb_array_elements(data_column) AS elem
  WHERE elem->>'id' = new_obj->>'id'
);

封装成可复用函数

如果需要多次调用,建议封装成PL/pgSQL函数:

CREATE OR REPLACE FUNCTION replace_jsonb_array_item(
  original_arr jsonb,
  new_item jsonb
) RETURNS jsonb AS $$
BEGIN
  RETURN (
    SELECT jsonb_agg(
      CASE WHEN elem->>'id' = new_item->>'id' THEN new_item ELSE elem END
    )
    FROM jsonb_array_elements(original_arr) AS elem
  );
END;
$$ LANGUAGE plpgsql;

调用函数更新的示例:

UPDATE target_table
SET data_column = replace_jsonb_array_item(
  data_column,
  '{"id": "1231-213-331", "name": "New Name For Object One"}'::jsonb
)
WHERE EXISTS (
  SELECT 1
  FROM jsonb_array_elements(data_column) AS elem
  WHERE elem->>'id' = '1231-213-331'
);

补充说明

  • 你之前尝试的||操作符是拼接数组,会在原数组末尾新增元素而非替换,不符合需求;
  • jsonb_set需要明确知道元素在数组中的索引,而你无法直接通过ID获取索引,因此展开聚合的方式更适配当前场景。

内容的提问来源于stack exchange,提问作者Ethan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 07:17:39