使用jsonb_set()进行条件更新
我在Postgres 11.3数据库中有一个带有jsonb列的表。
尝试更新嵌套数组名称中的所有对象"iProps"。
如果路径{iProps -> value -> rules -> ao -> sc}是对象,则应将路径从对象更新为具有以下值的字符串: {iProps
-> value -> rules -> ao -> sc -> name}
如果{iProps -> value -> rules -> ao -> sc}不存在该路径,则该对象应保持不变。
使用查询测试设置:小提琴链接
所需结果:
{    "iProps": [
        {
            "value": {
                "rules": [
                    {
                        "ao": {
                            "set": "get"
                        },
                        "name": "PRule"
                    },
                    {
                        "ao": {
                            "sc":  "name1"
                        }
                    },
                    {
                        "ao": {
                            "sc": "name2"
                        }
                    },
                    {
                        "ao": {
                            "sc":  "name3"                            
                        }
                    }
                ]
            }
        }
    ]
}
我已经修改了查询并链接到小提琴中。有人可以看看是否正确吗?
回答:
平原CASE应该有所作为。
UPDATE table_ tSET    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
<>在这里
拨弄 (Postgres 11!)
为了同时满足您在更新中添加的第二个过滤器(必须是一个 对象
),请使用进行检查jsonb_typeof()。
小提琴中的查询似乎不必要地复杂(tl;
dr)。同样,它不保留  。如果实际上不相关,请省略WITH ORDINALITY并ORDER BY进一步简化:
UPDATE table_ tSET    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
<>在这里拨弄
通常,这仍会保留数组元素的顺序(与原始数组不同)。不能保证具有两个聚合级别。
以上是 使用jsonb_set()进行条件更新 的全部内容, 来源链接: utcz.com/qa/412517.html


