I want to query a table that has JSON data. The data of the column detail in the table details are as follows.
id | 1
detail | {
myCompany: [{ email: 'company@company.com', inProfit: true }],
myData: [
{ email: 'example@example.com', personalUse: true },
{ email: 'test@test.com', personalUse: false },
{ email: 'test@example.com' },
],
};
The JSON value of the column detail is as follows
{
"myCompany":[
{
"email":"company@company.com",
"inProfit":true
}
],
"myData":[
{
"email":"example@example.com",
"personalUse":true
},
{
"email":"test@test.com",
"personalUse":false
},
{
"email":"test@example.com",
}
]
}
I want a query that updates the myData
. If the myData
field doesn't contain personalUse
then update that field with personalUse:true
. In the given example { email: 'test@example.com' }
field should update as { email: 'test@example.com', personalUse: true }
You can use the below queries to try it locally.
CREATE TABLE details (id bigserial primary key, detail json not null);
INSERT INTO details (detail)
VALUES
('{"myCompany":[{"email":"company@company.com", "inProfit":true } ],
"myData":[{"email":"example@example.com", "personalUse":true },
{"email":"test@test.com", "personalUse":false },
{"email":"test@example.com"} ] }');
Please, someone, help me out.
Best Answer
I had fun with this one :) This leaves
personalUse
as-is when present, otherwise sets it to true, and should preserve all other key/values in in the toplevel object besidesmyData
and all keys other thanpersonalUse
in the innermost objects. What it is not - and I'm pretty sure cannot be - is remotely efficient, but that can't really be helped without using jsonb, adding indexes, and otherwise doing a lot of high-touch things. This should also work back to at least PG9.5, although I only tested as far back as 10.