[英]How to update multiple values in JSONB array Postgresql array object
I have a JSONB array below我在下面有一个 JSONB 数组
[
{"name":"test","age":"21","phone":"6589","town":"54"},
{"name":"test12","age":"67","phone":"6546","town":"54"}
]
Now I want to update town
, phone
, age
if name
is test .现在我想更新town
、 phone
、 age
,如果name
是测试。 How to update multiple values in JSONB array?如何更新 JSONB 数组中的多个值?
Below query will give you results which contains test
word in them.下面的查询将为您提供其中包含test
词的结果。 After you find these you can update any values in other columns.找到这些后,您可以更新其他列中的任何值。
CREATE TABLE TEST2 (
INFO JSON NOT NULL
);
INSERT INTO TEST2 (info)
VALUES('[
{"name":"test","age":"21","phone":"6589","town":"54"},
{"name":"test12","age":"67","phone":"6546","town":"54"},
{"name":"dest147","age":"67","phone":"6546","town":"54"}
]');
SELECT *
FROM TEST2,
json_array_elements(info) elem
WHERE elem ->> 'name' like '%test%';
You can update them dynamically by indexing each individual element:您可以通过索引每个单独的元素来动态更新它们:
For age :对于年龄:
WITH s AS
(
SELECT ('{'||idx-1||',age}')::text[] AS path
FROM tab
CROSS JOIN jsonb_array_elements(jsdata)
WITH ORDINALITY arr(j,idx)
WHERE j->>'name'='test'
)
UPDATE tab
SET jsdata = jsonb_set(jsdata,s.path,'"15"',false)
FROM s
For town :对于城镇:
WITH s AS
(
SELECT ('{'||idx-1||',town}')::text[] AS path
FROM tab
CROSS JOIN jsonb_array_elements(jsdata)
WITH ORDINALITY arr(j,idx)
WHERE j->>'name'='test'
)
UPDATE tab
SET jsdata = jsonb_set(jsdata,s.path,'"55"',false)
FROM s
For phone :对于电话:
WITH s AS
(
SELECT ('{'||idx-1||',phone}')::text[] AS path
FROM tab
CROSS JOIN jsonb_array_elements(jsdata)
WITH ORDINALITY arr(j,idx)
WHERE j->>'name'='test'
)
UPDATE tab
SET jsdata = jsonb_set(jsdata,s.path,'"1111"',false)
FROM s
Or directly at a time :或直接一次:
WITH s AS
(
SELECT ('{'||idx-1||',phone}')::text[] AS path_phone,
('{'||idx-1||',town}')::text[] AS path_town,
('{'||idx-1||',age}')::text[] AS path_age
FROM tab
CROSS JOIN jsonb_array_elements(jsdata)
WITH ORDINALITY arr(j,idx)
WHERE j->>'name'='test'
)
UPDATE tab
SET jsdata = jsonb_set(jsonb_set(jsonb_set(jsdata,
s.path_phone,
'"1111"',
false),
path_town,
'"55"',
false),
s.path_age,
'"20"',
false)
FROM s
This query is longer, but it should clarify expanding the original column to make the replacements:此查询更长,但它应该阐明扩展原始列以进行替换:
with injson as (
select '[
{"name":"test","age":"21","phone":"6589","town":"54"},
{"name":"test12","age":"67","phone":"6546","town":"54"}
]'::jsonb as jarray
), substitution as (
select '{"name": "test", "age": "22", "phone": "6590", "town": "55"}'::jsonb as jnew
), expand as (
select jsonb_array_elements(jarray) as jold
from injson
), cond_update as (
select coalesce(s.jnew, e.jold) as element
from expand e
left join substitution s
on s.jnew->>'name' = e.jold->>'name'
)
select jsonb_agg(element) as result
from cond_update;
result
--------------------------------------------------------------------------------------------------------------------------------
[{"age": "22", "name": "test", "town": "55", "phone": "6590"}, {"age": "67", "name": "test12", "town": "54", "phone": "6546"}]
(1 row)
Based on the description of your table, it should look something like this:根据您的表的描述,它应该如下所示:
with substitution as (
select '{"name": "test", "age": "22", "phone": "6590", "town": "55"}'::jsonb as jnew
), expand as (
select id, jsonb_array_elements("caloriesConsumption") as jold
from "calorieTracker"
where id = 1
), cond_update as (
select id, coalesce(s.jnew, e.jold) as element
from expand e
left join substitution s
on s.jnew->>'name' = e.jold->>'name'
)
update "calorieTracker"
set "caloriesConsumption" = cu.element
from cond_update
where cond_update.id = "calorieTracker".id;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.