#sql #postgresql #jsonb
#sql #postgresql #jsonb
Вопрос:
У меня есть следующий JSON, сохраненный в столбце «Информация»
{
"customConfig": {
"isCustomGoods": 1
},
"new_addfields": {
"data": [
{
"val": {
"items": [
{
"Code": "calorie",
"Value": "365.76"
},
{
"Code": "protein",
"Value": "29.02"
},
{
"Code": "fat",
"Value": "23.55"
},
{
"Code": "carbohydrate",
"Value": "6.02"
},
{
"Code": "spirit",
"Value": "1.95"
}
],
"storageConditions": "",
"outQuantity": "100"
},
"parameterType": "Nutrition",
"name": "00000000-0000-0000-0000-000000000001",
"label": "1"
},
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "true"
}
]
}
}
Я хочу обновить значение вложенного json
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "true"
}
и установите «val» на «Yes» str, чтобы результат был таким
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "Yes"
}
Как я могу это сделать? Предполагая, что мне нужно обновить это значение в json для многих записей в базе данных
Комментарии:
1. Является ли ваша структура JSON фиксированной или ее можно изменить
Ответ №1:
Учитывая, что у вас есть постоянная структура JSON и первичный ключ в вашей таблице.Идея состоит в том, чтобы получить точный путь к элементу val
, имеющему значение true
(которое может быть с любым индексом в массиве), а затем заменить его на желаемое значение. Итак, вы можете написать свой запрос, как показано ниже:
with cte as (
select
id,
('{new_addfields,data,'||index-1||',val}')::text[] as json_path
from
test,
jsonb_array_elements(info->'new_addfields'->'data')
with ordinality arr(vals,index)
where
arr.vals->>'val' ilike 'true'
)
update test
set info = jsonb_set(info,cte.json_path,'"Yes"',false)
from cte
where test.id=cte.id;
Ответ №2:
Мы можем использовать jsonb_set()
то, что доступно из Postgres 9.5
Из документов:
jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])
Запрос для обновления вложенного объекта:
UPDATE temp t
SET info = jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
where id = 1;
Его также можно использовать в запросе select:
SELECT
jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
FROM temp t
LIMIT 1;