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
)
Related
Not sure what's wrong with this below SQL query. I am getting below error message
'Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.'
Can anyone please help me to fix this query
DECLARE #json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "gender" : "Female" },
{ "id" : 2, "name" : "Long Tail", "gender" : "Female" },
{ "id" : 3, "name" : "Scratch", "gender" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "gender" : "Male" },
{ "name" : "Fluffy", "gender" : "Male" },
{ "name" : "Wag", "gender" : "Female" }
]
}
}'
SELECT * FROM OPENJSON(#json, '$.pets.cats')
WITH(
[Cat Id] int,
[Cat Name] varchar(60),
[Gender] varchar(6),
[Cats] nvarchar(max)
);
P.S. I am using SQL server 2017 14.0
I have data in PersonalDetails table in JSON format, I am trying to parse the data in a single query, currently I am using JSON_TABLE functions, in my query I am only able to parse only one column, if I try to use JSON_TABLE functions twice it throwing me an error, is their a way to parse all the columns in a single query? or is their any other function apart from JSON_TABLE?
Sample Data
{
"FirstName" : "John",
"LastName" : "Doe",
"Job" : "Clerk",
"Address" : {
"Street" : "99 My Street",
"City" : "My City",
"Country" : "UK",
"Postcode" : "A12 34B"
},
"ContactDetails" : {
"Email" : "john.doe#example.com",
"Phone" : "44 123 123456",
"Twitter" : "#johndoe"
},
"DateOfBirth" : "01-JAN-1980",
"Active" : true
}
My Query
SELECT
FirstName,
LastName,
Job,
Street,
City,
Country,
Postcode,
ContactDetails,
DateOfBirth,
Active
FROM
JSON_TABLE(tab.Address, '$' COLUMNS
( Address VARCHAR(255) PATH '$.Street',
City VARCHAR(255) PATH '$.City',
Country VARCHAR(255) PATH '$.Country',
Postcode VARCHAR(255) PATH '$.Postcode',
)) JT,
PersonalDetails tab;
with PersonalDetails (jsn) as (
select '{
"FirstName" : "John",
"LastName" : "Doe",
"Job" : "Clerk",
"Address" : {
"Street" : "99 My Street",
"City" : "My City",
"Country" : "UK",
"Postcode" : "A12 34B"
},
"ContactDetails" : {
"Email" : "john.doe#example.com",
"Phone" : "44 123 123456",
"Twitter" : "#johndoe"
},
"DateOfBirth" : "01-JAN-1980",
"Active" : true
}' from dual
)
select jt.* from PersonalDetails, json_table (
PersonalDetails.jsn, '$'
COLUMNS
Firstname VARCHAR2(30) PATH '$.FirstName',
Address VARCHAR2(255) PATH '$.Address.Street',
City VARCHAR2(255) PATH '$.Address.City',
Country VARCHAR2(255) PATH '$.Address.Country',
Postcode VARCHAR2(255) PATH '$.Address.Postcode',
dob VARCHAR2(11) PATH '$.DateOfBirth',
email VARCHAR2(50) PATH '$.ContactDetails.Email'
) jt;
You could use the NESTED clause:
with PersonalDetails (data) as (
select
'{
"FirstName" : "John",
"LastName" : "Doe",
"Job" : "Clerk",
"Address" : {
"Street" : "99 My Street",
"City" : "My City",
"Country" : "UK",
"Postcode" : "A12 34B"
},
"ContactDetails" : {
"Email" : "john.doe#example.com",
"Phone" : "44 123 123456",
"Twitter" : "#johndoe"
},
"DateOfBirth" : "01-JAN-1980",
"Active" : true
}'
from dual
)
SELECT jt.*
FROM PersonalDetails,
JSON_TABLE(data, '$'
COLUMNS (FirstName VARCHAR2(50), LastName VARCHAR2(50), Job, Active,
NESTED ContactDetails COLUMNS (Email VARCHAR2(100), Phone)
)
) jt;
Output:
FIRSTNAME LASTNAME JOB ACTIVE EMAIL PHONE
---------- -------- ----- ------ -------------------- ---------------
John Doe Clerk true john.doe#example.com 44 123 123456
I have the following JSON which is stored in a jsonb field named "Data" in a PostgreSQL database:
{
"CompetitionData" :
{
"StartDate" : "12.06.2018",
"Name" : "TestCompetition",
"Competitors" :
[
{
"Id" : "100",
"Name" : "John",
"Age" : "24",
"Score" : "98",
"Shoes":
{
"Brand" : "Nike"
}
},
{
"Id" : "200",
"Name" : "Adam",
"Age" : "32",
"Score" : "78",
"Shoes":
{
"Brand" : "Adidas"
}
}
]
}
}
Im trying to get a specific entry in Competitors, like e.g.
SELECT * FROM Competitors WHERE Shoes = "Nike";
And the result must look like this:
{
"Id" : "100",
"Name" : "John",
"Age" : "24",
"Score" : "98",
"Shoes":
{
"Brand" : "Nike"
}
}
I tried the following query, but i keeps returning all competitors:
SELECT jsonb_array_elements(public."Competitions"."Data"->'CompetitionData'->'Competitors') as test
FROM public."Competitions" WHERE public."Competitions"."Data" #> '{"CompetitionData":{"Competitors":[{"Shoes":{"Brand":"Nike"}}]}}';
Is it possible to return just the competitor with Shoe Brand "Nike" ?
Use jsonb_array_elements in the from clause
SELECT j.* FROM
t cross join lateral
jsonb_array_elements(data->'CompetitionData'->'Competitors') as j(comp)
where j.comp->'Shoes'->>'Brand' = 'Nike'
Demo
Why do you want to save it in jsonb? Just normalize it into a database:
CREATE TABLE competitor_shoe (
name text PRIMARY KEY,
brand text NOT NULL
);
CREATE TABLE competitor (
id int PRIMARY KEY,
name text NOT NULL,
age int NOT NULL,
score int NOT NULL,
shoe text NOT NULL REFERENCES competitor_shoe(name)
);
CREATE TABLE competition (
name text PRIMARY KEY,
start_date date NOT NULL
);
CREATE TABLE competition_competitor (
competition text REFERENCES competition,
competitor int REFERENCES competitor,
PRIMARY KEY (competition,competitor)
);
INSERT INTO competitor_shoe
VALUES ('shoes1', 'Nike'),
('shoes2', 'Adidas');
INSERT INTO competitor
VALUES (100,'John',24,98,'shoes1'),
(200,'Adam',32,78,'shoes2');
INSERT INTO competition
VALUES (
'TestCompetition',
'12.06.2018'
);
INSERT INTO competition_competitor
VALUES ('TestCompetition', 100), ('TestCompetition', 200);
-- query the data
SELECT *
FROM competitor c
JOIN competitor_shoe cs
ON c.shoe = cs.name
WHERE brand = 'Nike';
-- query the data and return it as json object
SELECT to_jsonb(c) || jsonb_build_object('shoe', to_jsonb(cs)) as data
FROM competitor c
JOIN competitor_shoe cs
ON c.shoe = cs.name
WHERE brand = 'Nike';
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
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