Я изучаю JSONB в PostgreSQL версии - 11.6. У меня есть требование, где я хочу обновить все вхождения, где появляется определенное условие.
Рассмотрим приведенный ниже пример:
CREATE TABLE parts(id bigint NOT NULL GENERATED ALWAYS AS IDENTITY, parts_data jsonb);
insert into parts (parts_data) values
( '{
"Parts": {
"CreatedBy": "M95183638_95183638",
"PartsId": "00cb9cd6-37c5-41ca-b61c-a0f275d5d913",
"PartData": {
"Vendors": [
{
"VendorId": "1",
"Preferences": [
{
"CategoryId": 5582,
"SubcategoryId": 5583
},
{
"CategoryId": 5584,
"SubcategoryId": 5700
},
{
"CategoryId": 5582,
"SubcategoryId": 5697
},
{
"CategoryId": 5854,
"ClassCodes": [
{
"ClassCode": 971011,
"IsCertifiable": false
}
]
}
]
}
]
}
}
}'::jsonb);
Я хочу обновить SubcategoryId для всех элементов, где CategoryId = 5582. Когда я запускаю приведенный ниже запрос, он обновит только 1 экземпляр categoryID.
with data as
(
select path
FROM parts np
, LATERAL ( select ARRAY['Parts', 'PartData','Vendors', (vndr.index - 1)::text, 'Preferences', (pref.index - 1)::text, 'SubcategoryId'] as path
FROM jsonb_array_elements(parts_data #> '{Parts,PartData, Vendors}') WITH ORDINALITY vndr(opt, index)
, jsonb_array_elements(vndr.opt->'Preferences') with ordinality as pref(opt, index)
WHERE pref.opt ->> 'CategoryId'= '5582'
) a
WHERE parts_data->'Parts' ->> 'PartsId'='00cb9cd6-37c5-41ca-b61c-a0f275d5d913'
)
update parts np
set parts_data = jsonb_set(np.parts_data, path, '44444'::jsonb, false)
from data p1
where np.parts_data->'Parts' ->> 'PartsId'='00cb9cd6-37c5-41ca-b61c-a0f275d5d913';
Чтобы обновить все экземпляры, я думал о циклическом прохождении всех вхождений и обновлении каждого экземпляра, но это не кажется чистым решением. Есть ли способ обновить все экземпляры, где CategoryId = '5582'
в одном операторе UPDATE?