簡體   English   中英

使用 jsonb_set() 更新僅影響嵌套數組中的一個 object

[英]UPDATE with jsonb_set() only affects one object in nested array

嘗試更新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數組中的第一個 object:

iProps -> value -> rules -> ao -> sc -> name = "name1"

但不是后續的:

iProps -> value -> rules -> ao -> sc -> name = "name2"
iProps -> value -> rules -> ao -> sc -> name = "name3" 

解釋

UPDATEFROM子句中的子選擇返回三行 但是目標表中的每一行只能在一個UPDATE命令中更新一次 結果是您只能看到這三行之一的效果。

或者,用手冊的話來說:

使用FROM時,應確保連接為要修改的每一行最多生成一個 output 行。 換句話說,目標行不應連接到來自其他表的多個行。 如果是這樣,那么只有一個連接行將用於更新目標行,但將使用哪一個是不容易預測的。

另外:不要將您的子查詢稱為“cte”。 這不是Common Table Expression

適當的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<> 在這里擺弄

在將它們聚合回數組之前,在每個 object(數組元素)上使用jsonb_set() 首先是葉級別,然后是更深層次。

我將id作為PRIMARY KEY添加到表中。 我們需要一些獨特的列來保持行分開。

添加的ORDER BY可能需要也可能不需要。 添加它以保證原始訂單。

當然,如果您的數據與樣本一樣有規律,則具有專用列的關系設計可能是一種更簡單的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM