Reputation: 121
I have a table that only have one column and the records are in json format as shown below:
The sample of each row is:
{
"id": "51cf9ff0-0ed5-11eb-8887-53248e3b2424",
"attributes": {
"source": "Google",
"medium": "cpc",
"visit_route": [
{
"time_on_page": 5,
"page_title": "Dedicated Servers"
},
{
"time_on_page": 1,
"page_title": "Partner Programme"
}
],
"keyword": null,
"visit_length": 6,
"started_at": "2020-10-15T10:56:31.51Z",
"ga_client_ids": [
"1213599109.1602733400"
],
"lead_id": "597b4cd6-d8fb-11e6-adad-17d0cee77142_ayRRmwDGKhjjSgdcMGDMGf"
}
}
The outcome should look like below:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|id |source |medium |visit_route |Keyword|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|51cf9ff0-0ed5-11eb-8887-53248e3b2424 |Google |cpc |[{"time_on_page": 5,"page_title": "Dedicated Servers"},{"time_on_page": 1,"page_title": "Partner Programme"}]| Null |
This sample is in each rows. I am new to parsing json in sql and have tried using the script below:
select id ,
attributes
from [StageDB].[dbo].[LeadFeeder_visits_json]
cross apply openjson(jsonObj)
WITH (
id nvarchar(100) ,
attributes nvarchar(max)
)
But the result I got as shown below:
I really need help.
Upvotes: 1
Views: 6214
Reputation: 6015
An alternative to OPENJSON
is to use JSON_VALUE
and JSON_QUERY
to pick out the pathways needed. The JSON functions can optionally specify whether or not a field is strictly required. For example, in the code the first JSON_VALUE
specifies the 'id' to be 'strict'-ly present in the JSON. If the 'id' field is not present the JSON_VALUE
function will return an error
JSON in a table
drop table if exists #json;
go
create table #json(
jsonObj nvarchar(max) not null);
go
insert #json(jsonObj) values (N'{
"id": "51cf9ff0-0ed5-11eb-8887-53248e3b2424",
"attributes": {
"source": "Google",
"medium": "cpc",
"visit_route": [
{
"time_on_page": 5,
"page_title": "Dedicated Servers"
},
{
"time_on_page": 1,
"page_title": "Partner Programme"
}
],
"keyword": null,
"visit_length": 6,
"started_at": "2020-10-15T10:56:31.51Z",
"ga_client_ids": [
"1213599109.1602733400"
],
"lead_id": "597b4cd6-d8fb-11e6-adad-17d0cee77142_ayRRmwDGKhjjSgdcMGDMGf"
}
}');
Query
select json_value(jsonObj, N'strict $.id') id,
json_value(jsonObj, N'$.attributes.source') [source],
json_value(jsonObj, N'$.attributes.medium') [medium],
json_query(jsonObj, N'$.attributes.visit_route') visit_route,
json_value(jsonObj, N'$.attributes.keyword') keyword
from #json;
Output
id source medium visit_route keyword
51cf9ff0-0ed5-11eb-8887-53248e3b2424 Google cpc [{time_on_page": 5, "page_title": "Dedicated Servers" }, { "time_on_page": 1, "page_title": "Partner Programme" } ] NULL
Upvotes: 0
Reputation: 81930
If you'll have multiple sets of ATTRIBUTES, then GMB is correct with the second cross apply
. If only one set, then you can get by with a single cross apply
.
Example
Select B.*
From YourTable A
Cross Apply OpenJSON(jsonObj) WITH (
id varchar(100) '$.id',
source varchar(100) '$.attributes.source',
medium varchar(100) '$.attributes.medium',
visit_route nvarchar(MAX) '$.attributes.visit_route' AS JSON,
keyword varchar(100) '$.attributes.keyword'
) B
Returns
Upvotes: 2
Reputation: 222382
You would need to openjson()
twice: once to unnest jsonObj
, and another time to access the nested attributes:
select x.id, y.source, y.medium, y.visit_route
from [StageDB].[dbo].[LeadFeeder_visits_json] l
cross apply openjson(l.jsonObj) with(
id nvarchar(100),
attributes nvarchar(max) as json
) x
cross apply openjson(x.attributes) with (
source nvarchar(100),
medium nvarchar(100),
visit_route nvarchar(max) as json
) y
Note that you need as json
when extracting nested json content.
Upvotes: 3