value -> rules -> a-6ren">
gpt4 book ai didi

sql - 使用 jsonb_set() 进行条件更新

转载 作者:行者123 更新时间:2023-12-04 03:42:08 27 4
gpt4 key购买 nike

我在 Postgres 11.3 数据库中有一个表,带有 jsonb柱子。
尝试更新嵌套数组名称中的所有对象 "iProps" .
如果路径{iProps -> value -> rules -> ao -> sc}是一个对象,那么路径应该从一个对象更新为一个具有值的字符串{iProps -> value -> rules -> ao -> sc -> name}如果路径{iProps -> value -> rules -> ao -> sc}不存在,则对象应保持不变。
使用查询测试设置:Fiddle link
想要的结果:

{
"iProps": [
{
"value": {
"rules": [
{
"ao": {
"set": "get"
},
"name": "PRule"
},
{
"ao": {
"sc": "name1"

}
},
{
"ao": {
"sc": "name2"

}
},
{
"ao": {
"sc": "name3"
}
}
]
}
}
]
}
我已经修改了查询并在 fiddle 中链接。有人可以看看它是否正确吗?

最佳答案

一个普通的 CASE 应该有所作为。

UPDATE table_ t
SET value_ = jsonb_set(value_, '{iProps}', sub2.new_prop, false)
FROM (
SELECT id
, jsonb_agg(jsonb_set(prop, '{value, rules}', new_rules, false)
ORDER BY idx1) AS new_prop
FROM (
SELECT t.id, arr1.prop, arr1.idx1
, jsonb_agg(CASE WHEN jsonb_typeof(rule #> '{ao,sc}') = 'object'
THEN jsonb_set(rule, '{ao,sc}', rule #> '{ao,sc,name}', false)
ELSE rule
END

ORDER BY idx2) AS new_rules
FROM table_ t
, jsonb_array_elements(value_->'iProps') WITH ORDINALITY arr1(prop,idx1)
, jsonb_array_elements(prop->'value'->'rules') WITH ORDINALITY arr2(rule,idx2)
GROUP BY t.id, arr1.prop, arr1.idx1
) sub1
GROUP BY id
) sub2
WHERE t.id = sub2.id;
db<> fiddle here (Postgres 11!)
要满足您在更新中添加的第二个过滤器(必须是对象),请查看 jsonb_typeof() .
your fiddle中的查询似乎不必要地复杂(tl;dr)。此外,它不保留 数组元素的原始顺序 .如果这实际上无关紧要,请省略 WITH ORDINALITYORDER BY并进一步简化:
UPDATE table_ t
SET value_ = jsonb_set(value_, '{iProps}', sub2.new_prop, false)
FROM (
SELECT id
, jsonb_agg(jsonb_set(prop, '{value, rules}', new_rules, false)) AS new_prop
FROM (
SELECT t.id, prop
, jsonb_agg(CASE WHEN jsonb_typeof(rule #> '{ao,sc}') = 'object'
THEN jsonb_set(rule, '{ao,sc}', rule #> '{ao,sc,name}', false)
ELSE rule
END) AS new_rules
FROM table_ t
, jsonb_array_elements(value_->'iProps') prop
, jsonb_array_elements(prop->'value'->'rules') rule
GROUP BY t.id, prop
) sub1
GROUP BY id
) sub2
WHERE t.id = sub2.id;
db<> fiddle here
这通常仍然保留数组元素的顺序(与您的原始顺序不同)。两个级别的聚合无法保证。
看:
  • PostgreSQL unnest() with element number

  • 在我对您之前的相关问题的回答中提供了更多建议:
  • UPDATE with jsonb_set() only affects one object in nested array
  • 关于sql - 使用 jsonb_set() 进行条件更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65817635/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com