From table rows in my PostgreSQL 12.8 database, I am trying to remove an object from an array, but instead it is deleting whole array of objects from the table.
settings
column holds below array of objects:
[
{
"id": 100,
"name": "testOne",
"settings": "settingOne"
},
{
"id": 101,
"name": testTwo,
"settings": "settingTwo"
},
]
I have three rows in the users
table with the column settings
of type jsonb
that holds an array of objects.
I want to delete the object with id = 101 for all users. I tried the below query:
update users
set settings =
jsonb_set(settings , '{settings}', (settings->'id') - (select distinct position-1 from users, jsonb_array_elements(settings)
with ordinality arr(elem, position) WHERE elem->>'id' = '101')::int)
By executing the above query it is deleting everything from the settings. How can I modify the above query in order to achieve the below result?
[
{
"id": 100,
"name": "testOne"
"settings": "settingOne"
}
]
3
Answers
Use operator – only, no need to use
jsonb_set
.This is an optimized solution since it call
where
only once. if no data found it will return thesettings length
this way we will be sure nothing will be removed.The operator
-
Delete the array element with specified index (Negative integers count from the end).Demo here
This should do it:
fiddle
The added outer
WHERE
clause makes sure only rows are updated that actually change. You may have additional filters …This removes all objects from the array that have
"id": 101
. (There might be more than one.)To only remove the first match:
fiddle
Notably, do not repeat the table name in the correlated subquery, that would be expensive bloat – and require addtitional filters to link back to the updated table.
-1
is there because Postgres ordinality numbers start with 1 while JSON array elements start with 0.About
WITH ORDINALITY
:You can achieve below mentioned query once try it