I have a jsonb column such that:
| id | fee |
|----------|----------------------------------------|
| 1 | "[{"Step": "step1", "Value": "10"}]" |
| 2 | "[{"Step": "step1", "Value": "999"}]" |
| 3 | [] |
And I want to calculate the Value filed and add new property in the same fee
column such that:
ROUND((Value / 1.07),2)
I tried this below code but its not working.
update plans
set excess_fees = jsonb_set(plans.excess_fees, '{0, ValueExclGst}',
(select cast(round(cast(VALUE as decimal), 2) as text)
from jsonb_array_elements(plans.excess_fees->'Value') as VALUE));
The output looks like this:
| id | fee |
|----|-----|
| 1 | "[{"Step": "step1", "Value": "10", "ValueExclGst":"9.35"}]" |
| 2 | "[{"Step": "step1", "Value": "999", "ValueExclGst": "933.64"}]" |
| 3 | [] |
How shall I do in Postgres since I am new to Jsonb?
Thank you for your time and answers.
2
Answers
There is another approach I found out to solve the given problem. Yet it only work for first index which means it will work for all the id{1,2,3} but for id{1}, it will just update the first index.
To rollback programmatically, we can use below code snippets :
jsonb_array_elements
andjsonb_set
would come handy for this. A working query:The query works in these phases:
Create a
fee_json
auxiliary statement using CTE by deflating thefee
array column. Nowfee_json
has a columnjson_data
with all the deflated jsonb objects along with the correspondingid
.Create another
updated_rows
auxiliary statement using the values fromfee_json
. In this statement, we’re inserting a new valueValueExclGst
in the jsonb using the value fromValue
field in jsonb. We array aggregate all such jsonb objects byid
usingjsonb_agg
.We update the value from
udpated_rows
using theid
field in ourplans
table.A working db-fiddle for better understanding.