web-dev-qa-db-ja.com

jsonb配列要素を値で削除します

単一のレコードの配列から値を削除する方法を理解しましたが、多くのレコードでそれを行う方法を理解しました。問題は、サブクエリの使用方法にあります。単一の要素のみを返す必要があるため。たぶん私のアプローチは間違っています。

 
指定された入力: '{attributes:[' is_new '、' is_old ']}' 
期待される結果 '{attributes:[' is_old ']}'#remove'is_new 'jsonb array 
 
から
 
実際の例:
#sku |プロパティ
#------- + -------------------------------- 
#nu3_1 | {+ 
#| "name": "silly_hodgkin"、+ 
#| "type": "food"、+ 
#| 「属性」:[+ 
#| "is_gluten_free"、+ 
#| "is_lactose_free"、+ 
#| "is_new" + 
#| ] + 
#| } 
 
 
#単一の配列要素を削除するクエリ:
 
 SELECT c.sku、jsonb_agg(el)FROM 
 catalog c JOIN(select sku、 jsonb_array_elements_text(properties-> 'attributes')as el from catalog)c2 ON c.sku = c2.sku where el'is_new '
 GROUP BY c.sku; 
 
#単一レコード内の単一配列要素を削除するクエリの更新
 
 UPDATEカタログSETproperties = jsonb_set(properties、 '{attributes}'、(
 SELECT jsonb_agg( el)FROM 
 catalog c JOIN(select sku、jsonb_array_elements_text(properties-> 'attributes')as el from catalog)c2 ON c.sku = c2.sku 
 WHERE el'is_new 'AND c .sku = 'nu3_1' 
 GROUP BY c.sku 
)
)WHERE sku = 'nu3_1'; 

再び問題はです。多くのデータベースレコードの値でjsonb配列要素を削除するにはどうすればよいですか?

9
simpleman

jsonb_set()および削除演算子- を使用します:

update catalog
set properties = 
    jsonb_set(properties, '{attributes}', (properties->'attributes') - 'is_new');

レキスターでテストしてください。

13
klin

だから、私はあなたが探しているQRYは次のとおりだと思います:

with q as (
  select distinct sku, jsonb_set(properties,'{attributes}',jsonb_agg(el) over (partition by sku),false) new_properties
  from (
    select 
      sku, jsonb_array_elements_text(properties->'attributes') as el, properties
    from catalog
  ) p
  where el != 'is_new'
)
update catalog set properties = q.new_properties from q where catalog.sku = q.sku
;

あなたのskuは少なくともUKであると私が仮定したことに注意してください!

1
Vao Tsun

あなたの解決策は機能します+あなたは私にウィンドウ関数のようないくつかの新しいものを指摘し、私に代替解決策のアイデアを与えました:

 WITH q as(
 SELECT c.sku as sku、jsonb_set(properties、 '{attributes}'、jsonb_agg(el))as new_properties 
 FROM catalog c JOIN(select sku 、jsonb_array_elements_text(properties-> 'attributes')as el from catalog)c2 ON c.sku = c2.sku where el!= 'is_new' 
 GROUP BY c.sku 
)
 UPDATEカタログSETproperties = q.new_properties FROM q WHERE catalog.sku = q.sku; 
0
simpleman