简体   繁体   English

从 JSON 数组字段中查找和/或删除某些元素的 PostgreSQL 查询

[英]PostgreSQL query that finds and/or deletes certain elements from JSON array field

We have a table with a jsonb[] column that has an array of JSON objects with various keys.我们有一个带有jsonb[]列的表,该列包含具有各种键的JSON对象数组。 The DB is PostgreSQL (v9.6)数据库是 PostgreSQL (v9.6)

----------------------------------------------------
| id | data (jsonb[])                              |
----------------------------------------------------
|  1 | [{a:1, B:2, c:3}, {a:4, c:5}, {a:6, B:7}]   |
|  2 | [{a:8}, {B:9, c:10}]                        |
|  3 | [{a:11}]                                    |
----------------------------------------------------

We'd like to remove or set to empty all the values of B:我们想删除或设置为清空B 的所有值

so, we'd like to get所以,我们想得到

---------------------------------------------------------------
| id | data (jsonb[])                                         |
---------------------------------------------------------------
|  1 | [{a:1, B:null/"", c:3}, {a:4, c:5}, {a:6, B:null/""}]  |
|  2 | [{a:8}, {B:null/"", c:10}]                             |
|  3 | [{a:11}]                                               |
---------------------------------------------------------------

or或者

------------------------------------------
| id | data (jsonb[])                    |
------------------------------------------
|  1 | [{a:1, c:3}, {a:4, c:5}, {a:6}]   |
|  2 | [{a:8}, {c:10}]                   |
|  3 | [{a:11}]                          |
------------------------------------------

If there is no simple way to update the B field, we'd be happy to find a way to get all records that have B: in data field, in that case, we can load all the record and process them outside DB.如果没有简单的方法来更新 B 字段,我们很乐意找到一种方法来获取所有具有 B 的记录:在数据字段中,在这种情况下,我们可以加载所有记录并在 DB 外处理它们。

So far we can't find a way to do it, not even to find all records that have the B: field.到目前为止,我们无法找到一种方法来做到这一点,甚至无法找到所有具有 B: 字段的记录。

Any ideas will be great, thank you!任何想法都会很棒,谢谢!

You can achieve it by UNNEST Array --> Subtract Element --> Aggregate approach您可以通过UNNEST Array --> Subtract Element --> Aggregate方法来实现

If you want to remove the Element then try this:如果要删除元素,请尝试以下操作:

select 
id,
jsonb_agg(y-'B') 
from test cross join lateral unnest(data) x(y)
group by id

DEMO 演示

If you want to set the value of element NULL then try this:如果要设置元素NULL的值,请尝试以下操作:

select 
id, 
jsonb_agg(jsonb_set(y,'{B}','null',false)) 
from test cross join lateral unnest(data) x(y)
group by id

DEMO 演示

EDIT as per Comment:根据评论编辑:

with cte as (
select 
id,
array_agg(y-'B') "data"
from test cross join lateral unnest(data) x(y)
group by id
)

update test t1 set data = t2.data from cte t2 where t1.id=t2.id;

FIDDLE 小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM