【问题标题】:POSTGRESQL: update jsonb if key:value doesn't exsitsPOSTGRESQL:如果键:值不存在则更新 jsonb
【发布时间】:2022-01-04 09:26:38
【问题描述】:

我想更新表中的一个 jsonb 列(示例):

CREATE TEMPORARY TABLE tmp_1 AS
SELECT 1 as id,'{"foo":1,"bar":2,"foo_bar":3}'::jsonb as jb_value;

以某种方式更新:

UPDATE tmp_1 
   SET jb_value = jb_value || '{"foo_bar":4, "foo_foo_bar":4}'
 WHERE id = 1;

会返回类似于:

Result:
{"foo":1,"bar":2,"foo_bar":[3,4],"foo_foo_bar":4}

|| 运算符不适合我,因为根据 docs:

注意:||运算符通过生成一个连接两个 JSON 对象 包含它们的键并集的对象,取第二个对象的 存在重复键时的值。所有其他情况都会生成 JSON 数组:首先,将任何非数组输入转换为单元素 数组,然后将两个数组连接起来。它不运行 递归地;只合并顶层数组或对象结构。

这将返回键 "foo_bar" 的替换值,这是我不想要的

Result:
{"foo":1,"bar":2,"foo_bar":4,"foo_foo_bar":4}

我还考虑了jsonb_insertjsonb_set,但我不知道要更新或插入的密钥的路径。

提前致谢!

【问题讨论】:

  • 对于"foo_bar":4"foo_bar":[3,4] 的键值对不同,第一个是整数类型,第二个是数组类型
  • 这就是为什么我说“会返回类似的东西”;)所以它可能会转换为:{“foo”:[1],“bar”:[2],“foo_bar”:[3, 4],"foo_foo_bar":[4]}

标签: json postgresql sql-update jsonb


【解决方案1】:

试试这个:

SELECT jsonb_object_agg( COALESCE(a.key, b.key)
                       , CASE
                             WHEN a.key IS NULL THEN b.value
                             WHEN b.key IS NULL THEN a.value
                             ELSE '[]' :: jsonb || a.value || b.value
                         END
                       )
  FROM jsonb_each('{"foo":1,"bar":2,"foo_bar":3}'::jsonb) AS a
  FULL OUTER JOIN jsonb_each('{"foo_bar":4, "foo_foo_bar":4}' :: jsonb) AS b
     ON a.key = b.key

http://sqlfiddle.com/#!17/9eecb/84825

您可以将此查询插入到您的 UPDATE 语句中。

【讨论】:

  • 感谢@Edouard H. 的回答,但我有一个问题,当我已经有一个这样的值数组时:FROM jsonb_each('{"foo":1,"bar":2,"foo_bar":[3,5]}'::jsonb) AS a FULL OUTER JOIN jsonb_each('{"foo_bar":4, "foo_foo_bar":4}' :: jsonb) AS b ON a.key = b.key; 我得到嵌套数组:{"foo":1,"bar":2,"foo_bar":[[3,5],4],"foo_foo_bar":4} 对此有什么快速解决方法吗?
  • @w8forw8 - 根据您上次的评论更新了答案。
猜你喜欢
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多