Reading json array into rows in SQL Server - sql

Given the sample json data below, how can I write a query to pull the array data all in one step? My goal is to have one row for each item in the ActionRecs array (4). My actual json is more complicated but I think this gives a good example of my goal.
declare #json2 nvarchar(max)
set #json2 = '{
"RequestId": "1",
"ActionRecs": [
{
"Type": "Submit",
"Employee": "Joe"
},
{
"Type": "Review",
"Employee": "Betty"
},
{
"Type": "Approve",
"Employee": "Sam"
},
{
"Type": "Approve",
"Employee": "Bill"
}
]
}'
SELECT x.*
, JSON_QUERY(#json2, '$.ActionRecs') as ActionArray
from OPENJSON(#json2)
with (Id varchar(5) '$.RequestId') as x

One possible approach is to use OPENJSON() with explicit schema and an additional CROSS APPLY operator:
DECLARE #json nvarchar(max)
SET #json = N'{
"RequestId": "1",
"ActionRecs": [
{"Type": "Submit", "Employee": "Joe"},
{"Type": "Review", "Employee": "Betty"},
{"Type": "Approve", "Employee": "Sam"},
{"Type": "Approve", "Employee": "Bill"}
]
}'
SELECT i.Id, a.[Type], a.[Employee]
FROM OPENJSON(#json) WITH (
Id varchar(5) '$.RequestId',
ActionRecs nvarchar(max) '$.ActionRecs' AS JSON
) AS i
CROSS APPLY OPENJSON(i.ActionRecs) WITH (
[Type] nvarchar(max) '$.Type',
[Employee] nvarchar(max) '$.Employee'
) a
Output:
Id Type Employee
1 Submit Joe
1 Review Betty
1 Approve Sam
1 Approve Bill

Related

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

Extract text from JSON in SQL Server

I am trying to extract a specific value from a JSON column in SQL Server. Unfortunately I have read several posts on this topic but still cannot figure out how to translate their solutions to what I need. I am looking to extract "foo testing" but simply do not understand how to get at this with a nested JSON. Can someone please advise?
The structure of the JSON column is:
{
"values": [
{
"id": "x01",
"status": "STATUS1",
"subStatus": "SubStatus1",
"values": [
{
"key": "dropdown",
"value": "",
"optionType": null
}
]
},
...
{
"id": "x03",
"status": "STATUS3",
"subStatus": "SubStatus3",
"values": [
{
"key": "dropdown",
"value": "",
"optionType": null
},
{
"key": "textInput",
"value": null,
"optionType": null
},
{
"key": "checkbox1",
"value": true,
"optionType": null
},
{
"key": "textInput2",
"value": "foo testing",
"optionType": null
}
]
}
]
}
The statement depends on the structure of the parsed JSON, in your case you need to use two nested OPENJSON() calls and additinal APPLY operators. Note, that you need to use AS JSON in a "values" column definition to specify that the referenced property contains an inner JSON array and the type of that column must be nvarchar(max).
Test table:
DECLARE #json varchar(max) = '
{
"values": [
{
"id": "x01",
"status": "STATUS1",
"subStatus": "SubStatus1",
"values": [
{"key": "dropdown", "value": "", "optionType": null}
]
},
{
"id": "x03",
"status": "STATUS3",
"subStatus": "SubStatus3",
"values": [
{"key": "dropdown", "value": "", "optionType": null},
{"key": "textInput", "value": null, "optionType": null},
{"key": "checkbox1", "value": true, "optionType": null},
{"key": "textInput2", "value": "foo testing", "optionType": null}
]
}
]
}
'
SELECT JsonColumn
INTO JsonTable
FROM (VALUES (#json)) v (JsonColumn)
Statement:
SELECT j1.[id], j2.[key], j2.[value] -- or add all columns
FROM JsonTable t
CROSS APPLY OPENJSON(t.JsonColumn, '$.values') WITH (
[id] varchar(3) '$.id',
[status] varchar(30) '$.status',
[subStatus] varchar(30) '$.subStatus',
[values] nvarchar(max) '$.values' AS JSON
) j1
CROSS APPLY OPENJSON(j1.[values], '$') WITH (
[key] varchar(50) '$.key',
[value] varchar(50) '$.value',
[optionType] varchar(50) '$.optionType'
) j2
Result:
id key value
---------------------------
x01 dropdown
x03 dropdown
x03 textInput
x03 checkbox1 true
x03 textInput2 foo testing
you can use following query
;with summery as(
SELECT *
FROM OPENJSON((SELECT value FROM OPENJSON(#json)))
WITH (
id NVARCHAR(50) 'strict $.id',
status NVARCHAR(50) '$.status',
subStatus NVARCHAR(50) '$.subStatus',
[values] NVARCHAR(max) '$.values' AS JSON
)
)
select id,status,subStatus,[key],value,optionType from summery
CROSS APPLY OPENJSON(summery.[values])
WITH (
[key] NVARCHAR(50) '$.key',
[value] NVARCHAR(50) '$.value',
[optionType] NVARCHAR(50) '$.optionType'
);
demo in db<>fiddle

Transform properties from JSON array into comma-separated string

I have a string column in an SQL-Server table on Azure which contains the following data:
{
"status": "success",
"data": [
{
"name": "Jane",
"type": 0
},
{
"name": "John",
"type": 0
}
]
}
How can it be transformed into a comma-separated string containing "Jane, John"?
Here how to achieve this via a snippet of some of my older code, you should be able to loop through the table and do this for each row. There may be a quicker way of doing it but this will work.
DECLARE #JSON NVARCHAR(200) = '{"status": "success", "data": [{"name": "Jane", "type": 0},{"name": "John", "type": 0}]}',
#result nvarchar(max) = ''
SELECT #result = #result + [value] + N', '
FROM (
SELECT DISTINCT data.value
FROM OPENJSON(#JSON, '$.data') as jsondata
CROSS APPLY OPENJSON(jsondata.value) as data
WHERE data.[key] = 'name') a
select #result = substring(#result, 1, (LEN(#result)-1))
select #result

how to measure length of array inside array in json file using SQL OPENJSON function with cross APPLY

"table": [
{
"name": "Emergency",
"columns": [
{
"name": "ab",
"type": "long"
},
{
"name": "cd",
"type": "long"
},
{
"name": "ef",
"type": "long"
},
{
"name": "gh",
"type": "long"
},
],
"rows": [
[
0.55865,
2.0966,
0.4280,
1.4389
],
[
0.42490,
1.5723,
0.3601,
0.8031
]
]
}
]
}
so in this json, array object inside rows can be multiple(more than 2). so how to count object of array sinde 'rows' using OPENJSON SQL Server Function.
what I have done is, store this json into temporary table #TempAb and then
DECLARE #ab VARCHAR(MAX);
DECLARE #cd VARCHAR(MAX);
DECLARE #ef VARCHAR(MAX);
DECLARE #gh VARCHAR(MAX);
SELECT #ab=ab,#cd=cd,#ef=ef,#gh=gh from #TempAb as ab CROSS APPLY
OPENJSON(ab.RawData, '$.table') WITH
(
ab Varchar(MAX) '$.rows[0][0],
cd Varchar(Max) '$.rows[0][1],
ef Varchar(Max) '$.rows[0][2],
gh Varchar(Max) '$.rows[0][3]
);
so this query only returns data of the first object of rows, but I want data of all objects of rows. so I know the count then iterate this inside while loop
Solution:
SET #cnt_total = (SELECT COUNT(O.[key]) FROM (VALUES(#jsonvalue))V(J)
CROSS APPLY OPENJSON(V.J)
WITH([Object] nvarchar(MAX) '$.table[0].rows' AS JSON) M
CROSS APPLY OPENJSON(M.[Object]) O)
First you have to start with valid JSON, then something like this:
declare #json nvarchar(max) = N'
{
"table": [
{
"name": "Emergency",
"columns": [
{
"name": "ab",
"type": "long"
},
{
"name": "cd",
"type": "long"
},
{
"name": "ef",
"type": "long"
},
{
"name": "gh",
"type": "long"
}
],
"rows": [
[
0.55865,
2.0966,
0.4280,
1.4389
],
[
0.42490,
1.5723,
0.3601,
0.8031
]
]
}
]
}
'
select count(*) from
OPENJSON(#json, '$.table[0].rows') d

SQL Query to get the count of Json Array

I have the below Json object. How do I get the count of Object Array.
{
"Model": [
{
"ModelName": "Test Model",
"Object": [
{
"ID": 1,
"Name": "ABC"
},
{
"ID": 11,
"Name": "ABCD"
},
]
}]}
I tried the below query but seems JSON_Length was not available.
SELECT ModelName,
JSON_LENGTH(JsonData, '$.Model[0].Object')
FROM TabA
The expected output should be
ModelName COUNT
Test Model 2
If you have valid JSON (at the moment you have a trailing comma (,_ after one of your closing braces (})), then you could use OPENJSON and COUNT:
DECLARE #JSON nvarchar(MAX) = N'{
"Model": [
{
"ModelName": "Test Model",
"Object": [
{
"ID": 1,
"Name": "ABC"
},
{
"ID": 11,
"Name": "ABCD"
}
]
}]}';
SELECT M.ModelName,
COUNT(O.[key]) AS [Count]
FROM (VALUES(#JSON))V(J)
CROSS APPLY OPENJSON(V.J)
WITH(ModelName varchar(20) '$.Model[0].ModelName',
[Object] nvarchar(MAX) '$.Model[0].Object' AS JSON) M
CROSS APPLY OPENJSON(M.[Object]) O
GROUP BY M.ModelName;