JSON array parsing into rows - sql

I have JSON as below,
{
"value": [
{
"id": "123",
"createdDateTime": "2021-09-17T14:15:18Z"
},
{
"id": "124",
"createdDateTime": "2022-09-17T14:15:18Z"
}
]
}
am trying to get the output as 2 separate records and store it in clob column(values), any help would be appreciated.
values
{"id": "123","createdDateTime": "2021-09-17T14:15:18Z"}
{"id": "123","createdDateTime": "2021-09-17T14:15:18Z"}

You can use JSON_TABLE:
SELECT j.value
FROM table_name t
CROSS APPLY JSON_TABLE(
t.json_value,
'$.value[*]'
COLUMNS
value VARCHAR2(4000) FORMAT JSON PATH '$'
) j
Which, for the sample data:
CREATE TABLE table_name (json_value CLOB CHECK (json_value IS JSON));
INSERT INTO table_name (json_value)
VALUES ('{"value":[{
"id": "123",
"createdDateTime": "2021-09-17T14:15:18Z"
},
{
"id": "124",
"createdDateTime": "2022-09-17T14:15:18Z"
}]}')
Outputs:
VALUE
{"id":"123","createdDateTime":"2021-09-17T14:15:18Z"}
{"id":"124","createdDateTime":"2022-09-17T14:15:18Z"}
db<>fiddle here

Related

Update json data in oracle sql

This is my json data in one of the oracle sql columns "jsoncol" in a table named "jsontable"
{
"Company": [
{
"Info": {
"Address": "123"
},
"Name": "ABC",
"Id": 999
},
{
"Info": {
"Address": "456"
},
"Name": "XYZ",
"Id": 888
}
]
}
I am looking for an UPDATE query to update all the value of "Name" with a new value based on a particular "Id" value.
Thanks in advance
From Oracle 19, you can use JSON_MERGEPATCH:
UPDATE jsontable j
SET jsoncol = JSON_MERGEPATCH(
jsoncol,
(
SELECT JSON_OBJECT(
KEY 'Company'
VALUE JSON_ARRAYAGG(
CASE id
WHEN 999
THEN JSON_MERGEPATCH(
json,
'{"Name":"DEF"}'
)
ELSE json
END
FORMAT JSON
RETURNING CLOB
)
FORMAT JSON
RETURNING CLOB
)
FROM jsontable jt
CROSS APPLY JSON_TABLE(
jt.jsoncol,
'$.Company[*]'
COLUMNS(
json VARCHAR2(4000) FORMAT JSON PATH '$',
id NUMBER PATH '$.Id'
)
)
WHERE jt.ROWID = j.ROWID
)
)
Which, for the sample data:
CREATE TABLE jsontable (
jsoncol CLOB CHECK (jsoncol IS JSON)
);
INSERT INTO jsontable (jsoncol)
VALUES ('{
"Company": [
{
"Info": {
"Address": "123"
},
"Name": "ABC",
"Id": 999
},
{
"Info": {
"Address": "456"
},
"Name": "XYZ",
"Id": 888
}
]
}');
Then after the UPDATE, the table contains:
JSONCOL
{"Company":[{"Info":{"Address":"123"},"Name":"DEF","Id":999},{"Info":{"Address":"456"},"Name":"XYZ","Id":888}]}
db<>fiddle here
You can use REPLACE() within JSON_TABLE() function in order to update the value of the Name(from ABC to DEF) for a specific Id value(999) such as
UPDATE jsontable jt0
SET jsoncol = ( SELECT REPLACE(jsoncol,jt.name,'DEF')
FROM jsontable j,
JSON_TABLE(jsoncol,
'$' COLUMNS(NESTED PATH '$.Company[*]'
COLUMNS(
name VARCHAR2 PATH '$.Name',
id INT PATH '$.Id'
)
)
) jt
WHERE jt.id = 999
AND j.id = jt0.id )
for the DB version prior to 19 provided that the identity values(id) of the table and of the JSON values are unique throughout the table and each individual JSON value, respectively.
Demo

Is there an UPDATE equivalent command to SELECT json data

Is there a way to update the data retrieved from the below select (in this case, change "MS220" to something else)? It's difficult enough to do select from JSON in some cases. I'm not sure how to update just a single element.
CREATE TABLE JData (
JsonData nvarchar(max)
)
INSERT INTO JData
(JsonData)
VALUES
('[
{
"Categories": [
{
"QuerySourceNames": [
"QAsset"
],
"Id": "eceae85a-ffc6-49f4-8f6a-78ce2b4b274e",
"Name": "emsdba"
}
],
"Id": "525b4f07-0f67-43ac-8070-a0e6c1ceb1b9",
"Name": "MS220"
}
]')
SELECT
ParamName
FROM [dbo].[JData] jsonData
CROSS APPLY OPENJSON (jsonData)
WITH
(
Categories nvarchar(max) AS json,
Id uniqueidentifier,
ParamName varchar(10) '$.Name'
);
Try JSON_MODIFY() with the path '$[0].Name'
UPDATE d
SET jsonData = JSON_MODIFY(jsonData, '$[0].Name', 'New Value')
FROM [dbo].[JData] d
Results:
[
{
"Categories": [
{
"QuerySourceNames": [
"QAsset"
],
"Id": "eceae85a-ffc6-49f4-8f6a-78ce2b4b274e",
"Name": "emsdba"
}
],
"Id": "525b4f07-0f67-43ac-8070-a0e6c1ceb1b9",
"Name": "New Value"
}
]
db<>fiddle here

How to update value in nested json Postgres

I have following JSON stored in "Info" column
{
"customConfig": {
"isCustomGoods": 1
},
"new_addfields": {
"data": [
{
"val": {
"items": [
{
"Code": "calorie",
"Value": "365.76"
},
{
"Code": "protein",
"Value": "29.02"
},
{
"Code": "fat",
"Value": "23.55"
},
{
"Code": "carbohydrate",
"Value": "6.02"
},
{
"Code": "spirit",
"Value": "1.95"
}
],
"storageConditions": "",
"outQuantity": "100"
},
"parameterType": "Nutrition",
"name": "00000000-0000-0000-0000-000000000001",
"label": "1"
},
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "true"
}
]
}
}
I want to update value of nested json
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "true"
}
and set "val"to "Yes" str so the result should be like
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "Yes"
}
How can i do that ? Assuming that i need to update this value in json for many records in database
Considering you have a constant JSON Structure and a primary key in your table. Idea is to get the exact path of element val having value true (which can be at any index in the array) then replace it with desired value. So you can write your query like below:
with cte as (
select
id,
('{new_addfields,data,'||index-1||',val}')::text[] as json_path
from
test,
jsonb_array_elements(info->'new_addfields'->'data')
with ordinality arr(vals,index)
where
arr.vals->>'val' ilike 'true'
)
update test
set info = jsonb_set(info,cte.json_path,'"Yes"',false)
from cte
where test.id=cte.id;
DEMO
We can use jsonb_set() which is available from Postgres 9.5+
From Docs:
jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])
Query to update the nested object:
UPDATE temp t
SET info = jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
where id = 1;
It can also be used in select query:
SELECT
jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
FROM temp t
LIMIT 1;

JSON from SQL query with child level

I have a simple query in my database:
SELECT id, name FROM users FOR JSON AUTO, ROOT('users')
This returns the following JSON:
{
"users": [
{"id": "1", "name": "John"}
{"id": "2", "name": "Mike"}
]
}
I want to have the return with the following format:
{
"users": {
"list": [
{"id": "1", "name": "John"}
{"id": "2", "name": "Mike"}
]
}
}
Can I do this on SQL level by simply changing the query?
You may try with this:
Table:
CREATE TABLE users (
id varchar(1),
[name] varchar(50)
)
INSERT INTO users
(id, [name])
VALUES
('1', 'John'),
('2', 'Mike')
Statement:
SELECT users = (SELECT id, name FROM users FOR JSON AUTO, ROOT('list'))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
Result:
{"users":{"list":[{"id":"1","name":"John"},{"id":"2","name":"Mike"}]}}

How to select field values from array of objects?

I have a JSON column with following JSON
{
"metadata": { "value": "JABC" },
"force": false,
"users": [
{ "id": "111", "comment": "abc" },
{ "id": "222", "comment": "abc" },
{ "id": "333" }
]
}
I am expecting list of IDs from the query output ["111","222", "333"]. I tried following query but getting null value.
select colName->'users'->>'id' ids from tableName
How to get this specific field value from the array of object?
You need to extract the array as rows and then get the id:
select json_array_elements(colName->'users')->>'id' ids from tableName;
If you're using jsonb rather than json, the function is jsonb_array_elements.