尝试更新
jsonb
列中嵌套数组的所有元素,但仅更新一个元素。我的询问:
update table_
set value_ = jsonb_set(value_,cte.json_path,cte.namevalue,false) FROM (
select
vals2->'ao'->'sc'->'name' as namevalue,
('{iProps,'||index1-1||',value,rules,'||index2-1||',ao,sc}')::text[] as json_path
from
table_,
jsonb_array_elements(value_->'iProps')
with ordinality arr1(vals1,index1),
jsonb_array_elements(vals1->'value'->'rules')
with ordinality arr2(vals2,index2)
) AS cte;
查看带有示例值的演示:
db<>小提琴这里
我无法理解为什么此查询会更新
rules
数组中的第一个对象:
iProps -> value -> rules -> ao -> sc -> name = "name1"
但不是后续的:
iProps -> value -> rules -> ao -> sc -> name = "name2"
iProps -> value -> rules -> ao -> sc -> name = "name3"
FROM
的 UPDATE
子句中的子选择返回 三 行。但目标表中的每一行只能在单个 UPDATE
命令中更新一次。结果是您只能看到这三行中的one的效果。
或者,用手册的话来说:
使用
时,您应该确保连接最多产生一个 要修改的每一行的输出行。换句话说,目标行 不应连接到其他表中的多于一行。如果它 是的话,那么只有一个连接行将用于更新目标 行,但将使用哪一个是不容易预测的。FROM
旁白:不要将子查询命名为“cte”。这不是一个通用表表达式。
UPDATE
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(jsonb_set(rule, '{ao,sc}', rule #> '{ao,sc,name}', false)
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<>小提琴这里
在将每个对象(数组元素)聚合回数组之前,对每个对象(数组元素)使用
jsonb_set()
。首先在叶子级别,然后在更深的级别。
我将
id
作为 PRIMARY KEY
添加到表格中。我们需要一些独特的列来将行分开。
添加的
ORDER BY
可能需要也可能不需要。添加它是为了保证原始订单。
当然,如果您的数据与样本一样有规律,那么具有专用列的关系设计可能是一个更简单的选择。见