I have some json like this:
SET #json =N'[
{ "id" : 2,"name": "John", "surname": "Smith", "lastname":"", "age": 25 },
]'
I need to insert into table with a condition like IF LASTNAME IS EMPTY IN JSON THEN INSERT SURNAME INTO LASTNAME ELSE INSERT LASTNAME INTO LASTNAME
insert into mytable (id,firstname,lastname,age)
select id,name,case statement,age from openjson
WITH (id int 'strict $.id',name nvarchar(100) '$.name',case statement, age int '$.age');
Hi i think this query can respond :
DECLARE #json varchar(MAX)
SET #json =N'[
{ "id" : 2,"name": "John", "surname": "Smith", "lastname":"", "age": 25 },
{ "id" : 2,"name": "John", "surname": "Smith", "lastname":"TT", "age": 25 },
{ "id" : 2,"name": "John", "surname": "Smith", "lastname":"TEST", "age": 25 }
]'
select id,name,case when lastname = '' then surname else lastname end as lastnameup, age from openjson(#json)
WITH (id int 'strict $.id',name nvarchar(100) '$.name', surname nvarchar(100) '$.surname', lastname nvarchar(100) '$.lastname', age int '$.age');
EDIT for surname propose thanks to #Shnugo
Related
DECLARE #json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
]
}
}'
SELECT * FROM OPENJSON(#json, '$.pets.cats') WITH --we have the "main" json address here
(
id INT '$.id', --sub-address
name varchar(10) '$.name', --sub-address
sex varchar(10) '$.sex' --sub-address
)
The results are:
id
name
sex
1
Fluffy
Female
2
Long Tail
Female
3
Scratch
Male
I want to include another column which will not depend on the JSON, but be a custom specified string ("mammal"), so that the output is like this:
id
name
sex
Type
1
Fluffy
Female
mammal
2
Long Tail
Female
mammal
3
Scratch
Male
mammal
How would I achieve this?
You can simply add a constant in your SELECT statement:
DECLARE #json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
]
}
}'
SELECT *, 'mammal' AS Type FROM OPENJSON(#json, '$.pets.cats') WITH --we have the "main" json address here
(
id INT '$.id', --sub-address
name varchar(10) '$.name', --sub-address
sex varchar(10) '$.sex' --sub-address
)
If I do this I can get the first value in the array. But how can I get all of the values in the list ?
SELECT
JSON_VALUE('{"Distributor": [5030, 4000, 1231]}', '$.Distributor[0]') AS result;
SELECT value
FROM OPENJSON('{"Distributor": [5030, 4000, 1231]}','$.Distributor')
'$.Distributor' is the 'start path' to start looking for an array
You can take look at this article:
https://learn.microsoft.com/fr-fr/sql/relational-databases/json/json-data-sql-server?view=sql-server-2017
Using function Openjson and Outer apply
Example provided:
DECLARE #json NVARCHAR(MAX)
SET #json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "age": 25 },
{ "id" : 5,"info": { "name": "Jane", "surname": "Smith", "skills": ["SQL", "C#", "Azure"] }, "dob": "2005-11-04T12:00:00" }
]'
SELECT *
FROM OPENJSON(#json)
WITH (id int 'strict $.id',
firstName nvarchar(50) '$.info.name', lastName nvarchar(50) '$.info.surname',
age int, dateOfBirth datetime2 '$.dob',
skills nvarchar(max) '$.info.skills' as json)
outer apply openjson( skills )
with ( skill nvarchar(8) '$' )
EDIT Code with provided json :
DECLARE #json NVARCHAR(MAX)
SET #json = N'{"Distributor": [5030, 4000, 1231]}'
SELECT Distributor
FROM OPENJSON(#json)
WITH (Distributors nvarchar(max) '$.Distributor' as json)
outer apply openjson( Distributors )
with ( Distributor int '$' )
RESULT :
Distributor
5030
4000
1231
How can we use SQL to Convert a JSON statement into different tables?
For example we have JSON:
{"table1":
{"Name":"table1","Items":
[{"Id":1,"FirstName":"John",
"LastName":"Wen","Country":"UK",
"PostCode":1234,"Status":false,
"Date":"2018-09-18T08:30:32.91",}]},
"table2":
{"Name":"table2","Items":
[{"Id":1,"Name":"leo",
"StudentId":102,"CreatedDate":"2018-09-18","Location":"USA"}]}}
In the relational database, we will get two tables once the JSON is converted
For example, schema 'Table1':
Id FirstName LastName Country PostCode Status Date
1 John Wen UK 1234 false 2018-09-18T08:30:32.91
And the 'Table2' will look like:
Id Name StudentId CreateDate Location
1 Leo 102 2018-9-18 USA
Could anyone please give any advices on it.
You can do this using openjson and json_value functions. Try the following:
Declare #json nvarchar(max),#table1Items nvarchar(max), #table2Items nvarchar(max)
set #json='{
"table1": {
"Name": "table1",
"Items": [{
"Id": 1,
"FirstName": "John",
"LastName": "Wen",
"Country": "UK",
"PostCode": 1234,
"Status": false,
"Date": "2018-09-18T08:30:32.91"
}, {
"Id": 2,
"FirstName": "John1",
"LastName": "Wen1",
"Country": "UK1",
"PostCode": 12341,
"Status": true,
"Date": "2018-09-15T08:30:32.91"
}]
},
"table2": {
"Name": "table2",
"Items": [{
"Id": 1,
"Name": "leo",
"StudentId": 102,
"CreatedDate": "2018-09-18",
"Location": "USA"
}]
}
}'
set #table1Items=(select value from OpenJSON((select value from OpenJSON(#Json) where [key]='table1')) where [key]='Items')
set #table2Items=(select value from OpenJSON((select value from OpenJSON(#Json) where [key]='table2')) where [key]='Items')
--select for table 1
select JSON_VALUE(val,'$.Id') as ID,
JSON_VALUE(val,'$.FirstName') as FirstName,
JSON_VALUE(val,'$.LastName') as LastName,
JSON_VALUE(val,'$.Country') as Country,
JSON_VALUE(val,'$.PostCode') as PostCode,
JSON_VALUE(val,'$.Status') as Status,
JSON_VALUE(val,'$.Date') as Date
from
(
select value as val from openJSON(#table1Items)
) AS Table1JSON
--select for table 1
select JSON_VALUE(val,'$.Id') as ID,
JSON_VALUE(val,'$.Name') as FirstName,
JSON_VALUE(val,'$.StudentId') as LastName,
JSON_VALUE(val,'$.CreatedDate') as Country,
JSON_VALUE(val,'$.Location') as PostCode
from
(
select value as val from openJSON(#table2Items)
) AS Table2JSON
It is working exactly as you wanted. At the end, the two select statements return the tables as you mentioned. Just add them to your desired table using insert into select. I have also tried adding another object to table1 array and verified that it is working fine i.e. returning two rows for two objects. Hope this helps
If SQL Version 2016+ use OPENJSON AND with_clause:
https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql?view=sql-server-2017
DECLARE #JsonData NVARCHAR(MAX);
SET #JsonData = N'
{
"table1": {
"Name": "table1",
"Items": [
{
"Id": 1,
"FirstName": "John",
"LastName": "Wen",
"Country": "UK",
"PostCode": 1234,
"Status": false,
"Date": "2018-09-18T08:30:32.91"
},
{
"Id": 2,
"FirstName": "John1",
"LastName": "Wen1",
"Country": "UK1",
"PostCode": 12341,
"Status": true,
"Date": "2018-09-15T08:30:32.91"
}
]
},
"table2": {
"Name": "table2",
"Items": [
{
"Id": 1,
"Name": "leo",
"StudentId": 102,
"CreatedDate": "2018-09-18",
"Location": "USA"
}
]
}
}
';
--Table1
SELECT [a].[Id]
, [a].[FistName]
, [a].[Lastname]
, [a].[Country]
, [a].[PostCode]
, [a].[Status]
, [a].[Date]
FROM
OPENJSON(#JsonData, '$.table1.Items')
WITH (
[Id] INT '$.Id'
, [FistName] NVARCHAR(200) '$.FirstName'
, [Lastname] NVARCHAR(200) '$.LastName'
, [Country] NVARCHAR(200) '$.Country'
, [PostCode] NVARCHAR(200) '$.PostCode'
, [Status] NVARCHAR(200) '$.Status'
, [Date] DATETIME '$.Date'
) [a];
--Table2
SELECT [a].[Id]
, [a].[Name]
, [a].[StudentId]
, [a].[CreatedDate]
, [a].[Location]
FROM
OPENJSON(#JsonData, '$.table2.Items')
WITH (
[Id] INT '$.Id'
, [Name] NVARCHAR(200) '$.Name'
, [StudentId] INT '$.StudentId'
, [CreatedDate] DATETIME '$.CreatedDate'
, [Location] NVARCHAR(200) '$.Location'
) [a];
Try using OPENJSON function in SQL Server:
ReferenceLink_1
ReferenceLink_2
Referring to the example provided by Microsoft:
DECLARE #json NVARCHAR(MAX)
SET #json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "age": 25 },
{ "id" : 5,"info": { "name": "Jane", "surname": "Smith" }, "dob": "2005-11-04T12:00:00" }
]'
SELECT *
FROM OPENJSON(#json)
WITH (id int 'strict $.id',
firstName nvarchar(50) '$.info.name', lastName nvarchar(50) '$.info.surname',
age int, dateOfBirth datetime2 '$.dob')
when the JSON data has an array inside, for example:
DECLARE #json NVARCHAR(MAX)
SET #json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" },
"Phones": ["123","345","678"] // like here
}
]'
Is there any way to join the array on the parsed data to get something like this:
Id First Name Last Name Phone
2 John Smith 123
2 John Smith 345
2 John Smith 678
OUTER APPLY is your friend here. Let's mix up both kinds of rows for good measure.
DECLARE #json NVARCHAR(MAX)
SET #json = N'
[
{
"id": 2,
"info": {
"name": "John",
"surname": "Smith"
},
"age": 25,
"Phones": [
"123",
"345",
"678"
]
},
{
"id": 5,
"info": {
"name": "Jane",
"surname": "Smith"
},
"dob": "2005-11-04T12:00:00"
}
]'
SELECT id, [name], [surname], age, dateOfBirth, number
FROM (
SELECT *
FROM OPENJSON(#json)
WITH (
id INT 'strict $.id',
[name] NVARCHAR(50) '$.info.name',
[surname] NVARCHAR(50) '$.info.surname',
age INT,
dateOfBirth DATETIME2 '$.dob',
Phones NVARCHAR(MAX) AS JSON
)
) AS people
OUTER APPLY OPENJSON(Phones)
WITH (
number NVARCHAR(50) '$'
)
Result:
+----+------+---------+------+-----------------------------+--------+
| id | name | surname | age | dateOfBirth | number |
+----+------+---------+------+-----------------------------+--------+
| 2 | John | Smith | 25 | NULL | 123 |
| 2 | John | Smith | 25 | NULL | 345 |
| 2 | John | Smith | 25 | NULL | 678 |
| 5 | Jane | Smith | NULL | 2005-11-04 12:00:00.0000000 | NULL |
+----+------+---------+------+-----------------------------+--------+
Well, you can always do something like this:
SELECT ID, FirstName, LastName, value
FROM OPENJSON(#json)
WITH(ID int '$.id',
FirstName nvarchar(50) '$.info.name',
LastName nvarchar(50) '$.info.surname',
Phones nvarchar(max) '$.Phones' AS Json)
CROSS APPLY OPENJSON(Phones)
Hope this helps.
You will have to do it in two passes:
Extract for each person data and leaving array of phone numbers as JSON
Use CROSS/OUTER APPLY to parse array of phone numbers for each person and join result together
Something like this:
DECLARE #json NVARCHAR(MAX)
SET #json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "Phones": ["123","345","678"] },
{ "id" : 3,"info": { "name": "Jane", "surname": "Smith" }, "Phones": ["321","543"] }
]';
WITH CTE AS (
SELECT id, firstName, lastName, phones
FROM OPENJSON(#json)
WITH (
id INT 'strict $.id',
firstName NVARCHAR(50) '$.info.name',
lastName NVARCHAR(50) '$.info.surname',
phones NVARCHAR(MAX) '$.Phones' AS JSON
)
)
SELECT c.id, c.firstName, c.lastName, p.value as phone
FROM CTE c
CROSS APPLY OPENJSON(c.phones) p
You can use C# library
https://www.dotnet4techies.com/2018/07/convert-json-to-sql-format-using-csharp.html
It is a powerful tool and it maintains sql relationships from your Json if it has nested levels.
{
"ID":1,
"KEY1":"",
"ARRAYKEY1":[
{
"ARRAYKEY":""
"OBJECTKEY":{
"OBJ":""
}
}
]
}
Above is a JSON object I have stored in the database and I want to use OPENJSON to create a tabular format. I know I can do the whole OPENJSON WITH ( ) and manually create all the columns. I wanted to know if anyone has any idea of how to recursively or programatically create the table without having to identity each key for the table. I could end up having a couple dozen fields. I'm not worried about excluding any of the items. If I wanted to pull all the records back, where could I even begin with the new 2016 SQL Server?
Here is the official Documentation.
SET #json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "age": 25 },
{ "id" : 5,"info": { "name": "Jane", "surname": "Smith" }, "dob": "2005-11-04T12:00:00" }
]'
SELECT *
FROM OPENJSON(#json)
WITH (id int 'strict $.id',
firstName nvarchar(50) '$.info.name', lastName nvarchar(50) '$.info.surname',
age int, dateOfBirth datetime2 '$.dob')