Given the sample json data below, how can I write a query to pull the array data all in one step to individual column?
DECLARE #json NVARCHAR(MAX);
SET #json = N'{
"Title":"ReportExport",
"Attachment":"",
"Name":"Dhoni",
"FirstTextArea":"Dhoni",
"Radio":"First",
"CheckBox":"{C++~.Net}",
"FileUpload":"",
"FirstGroupitem":[
{
"Address":"QTUvNU55THBxT2hmVXFkWGpia2NJQT09",
"Age":"30",
"TestField":"",
"Country":"ind",
"SecondTextArea":"11"
},
{
"Address":"OVpuaXpxNTlrZWg4dGI4VXRYMUg0Zz09",
"Age":"30",
"TestField":"",
"Country":"us",
"SecondTextArea":"22"
},
{
"Address":"WGErNFU2S0tYekdsRWZTT2NxSzZLQT09",
"Age":"30",
"TestField":"",
"Country":"us",
"SecondTextArea":"33"
}
],
"SecondGroupitem":[
{
"Address1":"QTUvNU55THBxT2hmVXFkWGpia2NJQT09",
"Age1":"30"
},
{
"Address1":"OVpuaXpxNTlrZWg4dGI4VXRYMUg0Zz09",
"Age1":"30"
}
]
}';
Statement:
SELECT i.Title,i.Attachment,i.Name,i.FirstTextArea,i.Radio,i.CheckBox,i.FileUpload,'FirstGroupitem' as FirstGroupitem,
a.Address, a.Age,a.TestField,a.Country,a.SecondTextArea
FROM OPENJSON(#json)
WITH (
Title VARCHAR(max) N'$.Title',
Attachment VARCHAR(max) N'$.Attachment',
Name VARCHAR(max) N'$.Name',
FirstTextArea VARCHAR(max) N'$.FirstTextArea',
Radio VARCHAR(max) N'$.Radio',
CheckBox VARCHAR(max) N'$.CheckBox',
FileUpload VARCHAR(max) N'$.FileUpload',
FirstGroupitem nvarchar(max) '$.FirstGroupitem' AS JSON
) AS i
CROSS APPLY (
SELECT *
FROM OPENJSON(i.FirstGroupitem)
WITH (
Address VARCHAR(max) N'$.Address',
Age VARCHAR(max) N'$.Age',
TestField VARCHAR(max) N'$.TestField',
Country VARCHAR(max) N'$.Country',
SecondTextArea VARCHAR(max) N'$.SecondTextArea'
)
) a
I want output like this:
You need to join the items from the $.FirstGroupitem" and $."SecondGroupitem JSON arrays by index:
Statement:
SELECT
i.Title, i.Attachment, i.Name, i.FirstTextArea, i.Radio, i.CheckBox,
j.FirstGroupAddress, j.SecondGroupAddress
FROM OPENJSON(#json)
WITH (
Title VARCHAR(max) N'$.Title',
Attachment VARCHAR(max) N'$.Attachment',
Name VARCHAR(max) N'$.Name',
FirstTextArea VARCHAR(max) N'$.FirstTextArea',
Radio VARCHAR(max) N'$.Radio',
CheckBox VARCHAR(max) N'$.CheckBox',
FileUpload VARCHAR(max) N'$.FileUpload',
FirstGroupitem nvarchar(max) '$.FirstGroupitem' AS JSON,
SecondGroupitem nvarchar(max) '$.SecondGroupitem' AS JSON
) AS i
OUTER APPLY (
SELECT f2.Address AS FirstGroupAddress, s2.Address AS SecondGroupAddress
FROM OPENJSON (i.FirstGroupitem) f1
FULL JOIN OPENJSON (i.SecondGroupitem) s1 ON f1.[key] = s1.[key]
OUTER APPLY OPENJSON(f1.[value]) WITH (
Address varchar(100) '$.Address'
-- Additional columns here
) f2
OUTER APPLY OPENJSON(s1.[value]) WITH (
Address varchar(100) '$.Address1'
-- Additional columns here
) s2
) j
Result:
Title Attachment Name FirstTextArea Radio CheckBox FirstGroupAddress SecondGroupAddress
---------------------------------------------------------------------------------------------------------------------------------
ReportExport Dhoni Dhoni First {C++~.Net} QTUvNU55THBxT2hmVXFkWGpia2NJQT09 QTUvNU55THBxT2hmVXFkWGpia2NJQT09
ReportExport Dhoni Dhoni First {C++~.Net} OVpuaXpxNTlrZWg4dGI4VXRYMUg0Zz09 OVpuaXpxNTlrZWg4dGI4VXRYMUg0Zz09
ReportExport Dhoni Dhoni First {C++~.Net} WGErNFU2S0tYekdsRWZTT2NxSzZLQT09
Related
This is my query:
SELECT
JSON_QUERY(MyStringColumnWithJson, '$.Images') AS images
FROM MyTable
which returns a single field with the JSON data shown here below:
"{
"Images":
[
{"Name":"test1.jpeg","Description":"originalName1.jpeg"},
{"Name":"test2.jpeg","Description":"originalName2.jpeg"},
{"Name":"test3.jpeg","Description":"originalName3.jpeg"}
]
}"
How can I read the images result row by row into a temporary table structure?
Use OPENJSON which returns a data set, not JSON_VALUE, which returns a scalar value. For example:
DECLARE #JSON nvarchar(MAX) = N'{
"Images":
[
{"Name":"test1.jpeg","Description":"originalName1.jpeg"},
{"Name":"test2.jpeg","Description":"originalName2.jpeg"},
{"Name":"test3.jpeg","Description":"originalName3.jpeg"}
]
}';
SELECT *
FROM OPENJSON(#JSON, '$.Images')
WITH (Name nvarchar(128),
Description nvarchar(128))OJ;
SELECT I.[Name],
I.Description
FROM MyTable MT
CROSS APPLY OPENJSON(MT.YourJsonColumn, '$.Images')
WITH (Name nvarchar(128),
Description nvarchar(128)) I;
My SQL server
Query
DECLARE #json NVarChar(max)='{
"LoginName" : "SystemLogin",
"Authenticationtype" : "Windows",
"Roles":[ "bulkadmin", "setupadmin", "diskadmin" ],
"Pages":["SignUp","Login","ForgotPassword"]
}'
select LoginName,AuType,PageName,RoleName from OPENJSON(#json)
WITH
(
LoginName VARCHAR(20) '$.LoginName' ,
AuType VARCHAR(20) '$.Authenticationtype',
Pages nvarchar(MAX) '$.Pages' AS JSON,
Roles nvarchar(MAX) '$.Roles' AS JSON
)
CROSS APPLY OPENJSON(Pages) WITH
(
PageName VARCHAR(20) '$'
)
CROSS APPLY OPENJSON(Roles) WITH
(
RoleName VARCHAR(20) '$'
)
Here is OutPut
I want Expected Result
You need to use OPENJSON() with default schema when you parse $.Pages and $.Roles JSON arrays:
JSON:
DECLARE #json NVarChar(max)='{
"LoginName" : "SystemLogin",
"Authenticationtype" : "Windows",
"Roles":[ "bulkadmin", "setupadmin", "diskadmin" ],
"Pages":["SignUp","Login","ForgotPassword"]
}'
Statement:
SELECT LoginName, AuType, p.[value] AS PageName, r.[value] AS RoleName
FROM OPENJSON(#json) WITH (
LoginName VARCHAR(20) '$.LoginName' ,
AuType VARCHAR(20) '$.Authenticationtype',
Pages nvarchar(MAX) '$.Pages' AS JSON,
Roles nvarchar(MAX) '$.Roles' AS JSON
)
OUTER APPLY OPENJSON(Pages) p
OUTER APPLY OPENJSON(Roles) r
WHERE p.[key] = r.[key]
Result:
LoginName AuType PageName RoleName
----------------------------------------------
SystemLogin Windows SignUp bulkadmin
SystemLogin Windows Login setupadmin
SystemLogin Windows ForgotPassword diskadmin
..plagiarizing.. upvote the original author/source (#Zhorov)
DECLARE #json NVarChar(max)='{
"LoginName" : "SystemLogin",
"Authenticationtype" : "Windows",
"Roles":[ "bulkadmin", "setupadmin", "diskadmin" ],
"Pages":["SignUp","Login","ForgotPassword", "Page1", "Page2"]
}';
/*
"Roles":[ "bulkadmin", "setupadmin", "diskadmin", "Role1", "Role2", "Role3" ],
"Pages":["SignUp","Login","ForgotPassword"]
*/
/*
"Roles":[],
"Pages":[]
*/
SELECT LoginName, AuType, pr.PageName, pr.RoleName
FROM OPENJSON(#json) WITH (
LoginName VARCHAR(20) '$.LoginName' ,
AuType VARCHAR(20) '$.Authenticationtype',
Pages nvarchar(MAX) '$.Pages' AS JSON,
Roles nvarchar(MAX) '$.Roles' AS JSON
) as oj
outer apply
(
select p.value as PageName, r.value as RoleName
from
(
select *
from OPENJSON(oj.Pages)
) as p
full outer join
(
select *
from OPENJSON(oj.Roles)
) as r on p.[key] = r.[key]
) as pr;
I have the following JSON,
And I have no clue as to how to parse "Value" (When you run it in SQL you get 3 columns key, value and type)
Any ideas?
DECLARE #json NVARCHAR(MAX);
SET #json = N'[
{"salesDate":"2020-03-02","storeSales":[
{"storeId":"104","sales":[
{"productId":"20002","salesVolume":0.700,"salesQuantity":2,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"74301","salesVolume":0.750,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"642401","salesVolume":0.750,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"784001","salesVolume":2.100,"salesQuantity":3,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"1013801","salesVolume":1.500,"salesQuantity":2,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"1202801","salesVolume":0.750,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"1209901","salesVolume":0.700,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"1282201","salesVolume":0.750,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"3317301","salesVolume":1.500,"salesQuantity":2,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"4801301","salesVolume":0.700,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"5780106","salesVolume":6.000,"salesQuantity":2,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"7964902","salesVolume":0.375,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"10785001","salesVolume":0.750,"salesQuantity":1,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}},
{"productId":"11037501","salesVolume":1.500,"salesQuantity":2,"lastChanged":{"date":"2020-03-03","time":"07:28:06"}}]}]}]';
SELECT *
FROM OPENJSON(#json)
Assuming you wanted to get the sales data try this (although I am not 100% sure if this query offers the best performance)
SELECT [SalesDate], [StoreId], [ProductId], [SalesVolume], [SalesQuantity]
FROM OPENJSON(#json) WITH (
[SalesDate] DATETIME '$.salesDate',
[StoreSales] NVARCHAR(MAX) '$.storeSales' AS JSON
)
OUTER APPLY OPENJSON(StoreSales) WITH (
[StoreId] INT '$.storeId',
[Sales] NVARCHAR(MAX) '$.sales' AS JSON
)
OUTER APPLY OPENJSON(Sales) WITH (
[ProductId] INT '$.productId',
[SalesVolume] DECIMAL(18, 4) '$.salesVolume',
[SalesQuantity] INT '$.salesQuantity'
)
Value is the first object in your JSON array, which is itself another JSON object. SO you will have to read it using other SQL Server JSON utilities. For example:
SELECT JSON_VALUE(Value, '$.salesDate')
FROM OPENJSON(#json)
I just want to receive a json data and use it's fields as a table column for another queries.
I'm trying to make the value in the key "nameProperty" into a column in a table, and the value of the keys "newValue"fill the rows of that column.
For example:
i get a json file like this
{
"operation":{
"ID":"ABC",
"KinshipDescription":"--"
},
"fields":[
{
"property":{
"nameProperty":"ID",
"oldValue":"",
"newValue":"123456",
"confirmed":"false",
"labelProperty":"ID",
"oldValueDescription":"",
"newValueDescription":"123456"
}
},
{
"property":{
"nameProperty":"Name",
"oldValue":"",
"newValue":"John",
"confirmed":"false",
"labelProperty":"Name",
"oldValueDescription":"",
"newValueDescription":"John"
}
}
]
}
I want to extract the objects on the list "fields", but i only can make them an row for key, and another row for values like the script below makes.
DECLARE #jsonObj NVARCHAR(MAX)
--Set a result in
SET #jsonObj = (select JSON_Query(data, '$.fields') from table where id = 'ABC')
select * from openjson(#jsonObj)
with (Property nvarchar(255) '$.property.nameProperty',
newValue nvarchar(50) '$.property.newValue')
and I have no idea how I can do this
the results of this script is something like this
ID 123456
Name John
and the results that i want to see is
ID Name --column name, not a row
123456 John
The quickest (thought-wise, not necessarily performance) way I can come up with on this is using dynamic SQL. In fact, I'm pretty certain you'll have to use it.
Here's an example that can get you moving. You can run this in SSMS.
DECLARE #json NVARCHAR(MAX) =
'{
"operation":{
"ID":"ABC",
"KinshipDescription":"--"
},
"fields":[
{
"property":{
"nameProperty":"ID",
"oldValue":"",
"newValue":"123456",
"confirmed":"false",
"labelProperty":"ID",
"oldValueDescription":"",
"newValueDescription":"123456"
}
},
{
"property":{
"nameProperty":"Name",
"oldValue":"",
"newValue":"John",
"confirmed":"false",
"labelProperty":"Name",
"oldValueDescription":"",
"newValueDescription":"John"
}
}
]
}';
-- Variable to hold the column/values.
DECLARE #cols VARCHAR(MAX) = '';
-- Generate the column/value pairs.
SELECT
#cols = #cols
+ CASE WHEN ( LEN( #cols ) > 0 ) THEN ', ' ELSE '' END -- add comma if needed.
+ '''' + Properties.newValue + ''' AS [' + Properties.nameProperty + '] '
FROM OPENJSON( #json, '$.fields' ) WITH (
property NVARCHAR(MAX) '$.property' AS JSON
)
CROSS APPLY (
SELECT * FROM OPENJSON( property ) WITH (
nameProperty VARCHAR(50) '$.nameProperty',
oldValue VARCHAR(50) '$.oldValue',
newValue VARCHAR(50) '$.newValue',
confirmed VARCHAR(50) '$.confirmed',
labelProperty VARCHAR(50) '$.labelProperty',
oldValueDescription VARCHAR(50) '$.oldValueDescription',
newValueDescription VARCHAR(50) '$.newValueDescription'
)
) AS Properties;
-- Execute column/value pairs as dynamic SQL.
EXEC ( 'SELECT ' + #cols );
Which returns:
+--------+------+
| ID | Name |
+--------+------+
| 123456 | John |
+--------+------+
If you were to PRINT #cols you would see
'123456' AS [ID] , 'John' AS [Name]
A few quick notes:
Performance may vary.
Values are quoted but can be CAST if needed.
Included all 'property' fields in CROSS APPLY for example. Only specify what is needed.
Note the use of NVARCHAR when using AS JSON
May want to consider OUTER APPLY if there's potential for no 'property' present.
I have a column in a table that has Jsonstring text:
[
{
"PType":{"code":"9","name":"Hospitality"},
"PSubType":{"code":"901","name":"Hotel"},
"AType":{"code":"9","name":"Hospitality"},
"ASubType":{"code":"901","name":"Hotel"}
}
]
How can I divide that into multiple columns using sql server query?
With SQL-Server 2016+ there is native JSON support:
DECLARE #json NVARCHAR(MAX)=
N'[
{
"PType":{"code":"9","name":"Hospitality"},
"PSubType":{"code":"901","name":"Hotel"},
"AType":{"code":"9","name":"Hospitality"},
"ASubType":{"code":"901","name":"Hotel"}
}
]';
SELECT A.[key]
,JSON_VALUE(A.value,'$.code') AS Code
,JSON_VALUE(A.value,'$.name') AS [Name]
FROM OPENJSON(JSON_QUERY(#json,'$[0]')) A;
The result
key Code Name
---------------------------------
PType 9 Hospitality
PSubType 901 Hotel
AType 9 Hospitality
ASubType 901 Hotel
Some explanation:
With JSON_QUERY() you can get the element within the array, OPENJSON will find all objects within and return them as derived table.
JSON_VALUE will read the internals into columns.
Hint
with a version below v2016 you should use another tool or think about a CLR function...
In SQL Server 2016+ you can use a combination of openjson (more info here) and cross apply:
declare #json nvarchar(max) = '[ { "PType":{"code":"9","name":"Hospitality"}, "PSubType":{"code":"901","name":"Hotel"}, "AType":{"code":"9","name":"Hospitality"}, "ASubType":{"code":"901","name":"Hotel"} } ]'
select
[PT].[code] as Ptype_Code
,[PT].[name] as Ptype_Name
,[PS].[code] as PSubType_Code
,[PS].[name] as PSubType_Name
,[AT].[code] as AType_Code
,[AT].[name] as AType_Name
,[AS].[code] as ASubType_Code
,[AS].[name] as ASubType_Name
from openjson (#json)
with
(
PType nvarchar(max) as json,
PSubType nvarchar(max) as json,
AType nvarchar(max) as json,
ASubType nvarchar(max) as json
) as lev1
cross apply openjson (lev1.PType)
with
(
code int,
name nvarchar(100)
) as PT
cross apply openjson (lev1.PSubType)
with
(
code int,
name nvarchar(100)
) as PS
cross apply openjson (lev1.AType)
with
(
code int,
name nvarchar(100)
) as [AT]
cross apply openjson (lev1.ASubType)
with
(
code int,
name nvarchar(100)
) as [AS]
Result: