Reputation: 563
Table columns :
id
---------
details
My table column details has json object like
"data" : [ {
"name" : "luke",
"dob" : "12-10-90",
"addr" : "sample1",
},
{
"name" : "sam",
"dob" : "12-10-88",
"addr" : "sample2"
}
]
I want to write a query which will give me records like below :
| id | name| dob |addr |
|:-----|:----|:--- ------|:----------|
| 1 | luke| 12-10-90 | sample1 |
| 1 | sam | 12-10-88 | sample2 |
I tried with
select
ID,
JSON_VALUE(DETAILS, '$.data[0].name') ,
JSON_VALUE(DETAILS, '$.data[0].dob') ,
JSON_VALUE(DETAILS, '$.data[0].addr')
from
users;
RESULT WITH COUNT :
id cnt name dob addr
-- --- --------- -------- -------
1 5 luke 12-10-90 sample1
1 5 sam 12-10-88 sample2
2 5 awd 12-10-90 sample1
2 5 awdawdm 12-10-88 sample2
2 5 sevsevsev 12-10-88 sample2
EXPECTED
id cnt name dob addr
-- --- --------- -------- -------
1 2 luke 12-10-90 sample1
1 2 sam 12-10-88 sample2
2 3 awd 12-10-90 sample1
2 3 awdawdm 12-10-88 sample2
2 3 sevsevsev 12-10-88 sample2
Upvotes: 1
Views: 2082
Reputation: 15893
To get all the objects from json array along with other columns you can use OpenJson() and Cross Apply as below:
create table users (id int, details nvarchar(max));
insert into users values (1,N'{
"data":[
{
"name" : "luke",
"dob" : "12-10-90",
"addr" : "sample1"
},
{
"name" : "sam",
"dob" : "12-10-88",
"addr" : "sample2"
}
]
}');
Query:
SELECT u.id,count(details.name)over() cnt, details.name, details.dob,details.addr,details.*
FROM users u CROSS APPLY OPENJSON (u.details,N'$.data')
WITH (
[Name] VARCHAR(100) '$.name',
dob VARCHAR(10) '$.dob',
addr VARCHAR(100) '$.addr'
) AS details
Output:
id | cnt | name | dob | addr | Name | dob | addr |
---|---|---|---|---|---|---|---|
1 | 2 | luke | 12-10-90 | sample1 | luke | 12-10-90 | sample1 |
1 | 2 | sam | 12-10-88 | sample2 | sam | 12-10-88 | sample2 |
db<>fiddle here
Your code is working @DLV. Please check. There were problem with data formatting.
create table users (id int, details nvarchar(max));
insert into users values (1,N'{"data" :
[ { "name" : "luke", "dob" : "12-10-90", "addr" : "sample1", },
{ "name" : "sam", "dob" : "12-10-88", "addr" : "sample2" }
]}');
select
ID,
JSON_VALUE(DETAILS, '$.data[0].name') ,
JSON_VALUE(DETAILS, '$.data[0].dob') ,
JSON_VALUE(DETAILS, '$.data[0].addr')
from
users;
Output:
ID | (No column name) | (No column name) | (No column name) |
---|---|---|---|
1 | luke | 12-10-90 | sample1 |
db<>fiddle here
Upvotes: 3
Reputation: 899
You can loop through every record and use OPENJSON
to achieve this.
DECLARE @Id int
,@details NVARCHAR(MAX)
DROP TABLE IF EXISTS #Result
CREATE TABLE #Result (Id INT, [Name] VARCHAR(100),dob VARCHAR(10),addr VARCHAR(100))
DECLARE json_cursor CURSOR FOR
SELECT Id,details
FROM #DetailsTable -- Replace with your table
OPEN json_cursor
FETCH NEXT FROM json_cursor INTO @Id,@details
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN
INSERT INTO #Result
SELECT @Id AS Id,*
FROM OPENJSON(@details,N'$.data')
WITH (
[Name] VARCHAR(100) '$.name',
dob VARCHAR(10) '$.dob',
adrr VARCHAR(100) '$.addr'
)
END
FETCH NEXT FROM json_cursor INTO @Id,@details
END
CLOSE json_cursor
DEALLOCATE json_cursor
SELECT * FROM #Result
make sure your json object is enclosed in '{}'
like below
{"data" : [ {
"name" : "luke",
"dob" : "12-10-90",
"addr" : "sample1",
},
{
"name" : "sam",
"dob" : "12-10-88",
"addr" : "sample2"
}
]}
Upvotes: 2