POSTGRESQL:如果 key:value 不存在则更新 jsonb
POSTGRESQL: update jsonb if key:value doesn't exsits
我想更新 table 中的一个 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;
会 return 类似于 :
Result:
{"foo":1,"bar":2,"foo_bar":[3,4],"foo_foo_bar":4}
||
运算符对我不起作用,因为根据 docs:
Note: The || operator concatenates two JSON objects by generating an
object containing the union of their keys, taking the second object's
value when there are duplicate keys. All other cases produce a JSON
array: first, any non-array input is converted into a single-element
array, and then the two arrays are concatenated. It does not operate
recursively; only the top-level array or object structure is merged.
这会 return 替换键 "foo_bar"
的值, 我不想要 :
Result:
{"foo":1,"bar":2,"foo_bar":4,"foo_foo_bar":4}
我还考虑了 jsonb_insert
和 jsonb_set
,但我不知道要更新或插入的密钥的路径。
提前致谢!
试试这个:
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 语句中。
我想更新 table 中的一个 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;
会 return 类似于 :
Result:
{"foo":1,"bar":2,"foo_bar":[3,4],"foo_foo_bar":4}
||
运算符对我不起作用,因为根据 docs:
Note: The || operator concatenates two JSON objects by generating an object containing the union of their keys, taking the second object's value when there are duplicate keys. All other cases produce a JSON array: first, any non-array input is converted into a single-element array, and then the two arrays are concatenated. It does not operate recursively; only the top-level array or object structure is merged.
这会 return 替换键 "foo_bar"
的值, 我不想要 :
Result:
{"foo":1,"bar":2,"foo_bar":4,"foo_foo_bar":4}
我还考虑了 jsonb_insert
和 jsonb_set
,但我不知道要更新或插入的密钥的路径。
提前致谢!
试试这个:
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 语句中。