[英]Update array of objects in JSONB format PostgreSQL
I need to perform two update operations:我需要执行两个更新操作:
sample data in jsonb column: jsonb 列中的示例数据:
[
{ "tax": "yes", "tax_percent": 20, "used_when": "after" },
{ "tax": "no", "tax_percent": 20 },
{ "tax_percent": 20, "used_when": "before" }
]
and now:现在:
"tax" value needs to be updated from yes -> true, no OR null (not exists) means -> false “税”值需要从 yes -> true、no 或 null(不存在)更新意味着 -> false
"used_when" needs to be updated to "using" and if after -> true, if before OR null (not exists) means -> false “used_when”需要更新为“using”,如果之后 -> true,如果之前 OR null(不存在)意味着 -> false
so it will look like:所以它看起来像:
[
{ "tax": true, "tax_percent": 20, "using": true },
{ "tax": false, "tax_percent": 20, "using": false },
{ "tax": false, "tax_percent": 20, "using": false }
]
The values are optional so not all entries will have it, also this is single row in database column so this data in column needs to be updated for each row.这些值是可选的,因此并非所有条目都有它,这也是数据库列中的单行,因此需要为每一行更新列中的数据。
step-by-step demo:db<>fiddle 分步演示:db<>fiddle
UPDATE t -- 5
SET mydata = s.new_data
FROM (
SELECT
id,
json_agg((using_updated - 'used_when')::json) as new_data -- 4
FROM t,
json_array_elements(t.mydata) as elements, -- 1
jsonb_set(elements::jsonb, '{tax}', -- 2
CASE
WHEN elements ->> 'tax' = 'yes' THEN 'true'::jsonb
ELSE 'false'::jsonb
END
) as tax_updated,
jsonb_set(tax_updated::jsonb, '{using}', -- 3
CASE
WHEN tax_updated ->> 'used_when' = 'true' THEN 'true'::jsonb
ELSE 'false'::jsonb
END
) as using_updated
GROUP BY id
) s
WHERE s.id = t.id;
jsonb_set()
to insert new or update existing attributs within the array elements.现在您可以使用jsonb_set()
在数组元素中插入新的或更新现有的属性。 The CASE
clause does the condition check CASE
子句进行条件检查used_when
elements.消除剩余的used_when
元素。 Afterwards you can reaggregate the updated elements with json_agg之后,您可以使用 json_agg 重新聚合更新的元素UPDATE
做UPDATE
If your data is type json, you have to do the casts to jsonb since, there is no json_set()
.如果您的数据类型为 json,则必须对 jsonb 进行强制转换,因为没有json_set()
。 If not, you can ignore the casts, of course.如果没有,你当然可以忽略演员表。
However, as @a_horse_with_no_name correctly mentioned: You should think about not storing these data as pure JSON but extract them into a normalized relative database table structure, which make things much easier and more performant.但是,正如@a_horse_with_no_name 正确提到的那样:您应该考虑不将这些数据存储为纯 JSON,而是将它们提取到规范化的相对数据库表结构中,这会使事情变得更容易和更高效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.