如何更新JSONB数组Postgresql数组对象中的多个值
我在下面有一个JSONB数组如何更新JSONB数组Postgresql数组对象中的多个值,sql,json,postgresql,sql-update,jsonb,Sql,Json,Postgresql,Sql Update,Jsonb,我在下面有一个JSONB数组 [ {"name":"test","age":"21","phone":"6589","town":"54"}, {"name":"test12","age":"67","phone":"65
[
{"name":"test","age":"21","phone":"6589","town":"54"},
{"name":"test12","age":"67","phone":"6546","town":"54"}
]
现在我想更新城镇
,电话
,年龄
,如果姓名
是测试。
如何更新JSONB数组中的多个值?下面的查询将为您提供包含
test
word的结果。找到这些后,可以更新其他列中的任何值
您可以通过索引每个单独的元素来动态更新它们: 对于年龄:
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
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
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
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
对于城镇:
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
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
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
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
对于电话:
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
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
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
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
或一次直接:
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
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
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
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
此查询较长,但应明确扩展原始列以进行替换:
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)
根据表的描述,它应该如下所示:
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;
使用正确规范化的数据模型,这将非常容易。您确定要这样存储它吗?稍后您可能会遇到问题。尽管有点老了,我还是建议你阅读这篇关于为什么这可能是个坏主意的帖子。谢谢你的快速回复。我可以使用jsonb_集在一个查询中更新它吗?我在这里找到了它,但这里我们只能更新菜单名,但在我的情况下,我想在对象中添加一个或多个值。欢迎@AvinashJagtap,我还添加了一次执行的案例。非常感谢。我要试试这个。节省了我的时间。我在JSON中添加了另一个试图更新的对象。我们可以用现有对象替换整个对象而不是更改吗?@AvinashJagtap如果您想看到
更新
,那么将您的表信息添加到您的问题中。[{“name”:“test”,“age”:“21”,“phone”:“6589”,“town”:“54”},{“name”:“test12”,“age”:“67”,“phone”:“6546”,“town”:“54”},@AvinashJagtap这不是表。这只是一个JSON数组。您的数据库表名是什么,表中有哪些列?表名:CarriorTracker和两列id和CarriorConsumption。这是我的表infor在te表中,我有两列id是int,卡路里消耗是jsob数据类型。我想更新id 1,如果c_日期是外汇:“08/08/2020”,我想更新该对象。我希望我已经提供了exat信息。@AvinashJagtap我在回答中添加了一个示例更新语句。