发现 and/or 的 PostgreSQL 查询从 JSON 数组字段中删除某些元素
PostgreSQL query that finds and/or deletes certain elements from JSON array field
我们有一个 table 和一个 jsonb[]
列,该列有一个 JSON
对象数组,其中包含各种键。数据库是 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}] |
----------------------------------------------------
我们想删除或设置为清空 B 的所有值:
所以,我们想要
---------------------------------------------------------------
| 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}] |
---------------------------------------------------------------
或
------------------------------------------
| id | data (jsonb[]) |
------------------------------------------
| 1 | [{a:1, c:3}, {a:4, c:5}, {a:6}] |
| 2 | [{a:8}, {c:10}] |
| 3 | [{a:11}] |
------------------------------------------
如果没有简单的方法来更新 B 字段,我们很乐意找到一种方法来获取数据字段中包含 B: 的所有记录,在这种情况下,我们可以加载所有记录并处理他们在 DB 之外。
到目前为止我们找不到办法,甚至找不到所有具有 B: 字段的记录。
任何想法都会很棒,谢谢!
你可以通过UNNEST Array
-->Subtract Element
-->Aggregate
方法
实现
如果您想删除元素,请尝试以下操作:
select
id,
jsonb_agg(y-'B')
from test cross join lateral unnest(data) x(y)
group by id
如果你想设置元素 NULL
的值,那么试试这个:
select
id,
jsonb_agg(jsonb_set(y,'{B}','null',false))
from test cross join lateral unnest(data) x(y)
group by id
根据评论进行编辑:
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;
我们有一个 table 和一个 jsonb[]
列,该列有一个 JSON
对象数组,其中包含各种键。数据库是 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}] |
----------------------------------------------------
我们想删除或设置为清空 B 的所有值:
所以,我们想要
---------------------------------------------------------------
| 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}] |
---------------------------------------------------------------
或
------------------------------------------
| id | data (jsonb[]) |
------------------------------------------
| 1 | [{a:1, c:3}, {a:4, c:5}, {a:6}] |
| 2 | [{a:8}, {c:10}] |
| 3 | [{a:11}] |
------------------------------------------
如果没有简单的方法来更新 B 字段,我们很乐意找到一种方法来获取数据字段中包含 B: 的所有记录,在这种情况下,我们可以加载所有记录并处理他们在 DB 之外。
到目前为止我们找不到办法,甚至找不到所有具有 B: 字段的记录。
任何想法都会很棒,谢谢!
你可以通过UNNEST Array
-->Subtract Element
-->Aggregate
方法
如果您想删除元素,请尝试以下操作:
select
id,
jsonb_agg(y-'B')
from test cross join lateral unnest(data) x(y)
group by id
如果你想设置元素 NULL
的值,那么试试这个:
select
id,
jsonb_agg(jsonb_set(y,'{B}','null',false))
from test cross join lateral unnest(data) x(y)
group by id
根据评论进行编辑:
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;