I am using SSMS v18.12.1, and am trying to write a T-SQL query to extract specific values from multiple columns, and at times nested values.
In the example below, I would like to extract the DeliverySchedule @Type value, and the Details @Type and Details:candyLimit @Type value
{
"@type": "Test",
"OrderId": 6608216,
"deliverySchedule": {
"@DeliveryType": "Test",
"details": [
{
"@type": "Snickers",
"id": 657117,
"candyLimit": {
"@type": "UNRESTRICTED"
}
}
]
}
}
I am still pretty new to extracting JSON data. I have tried utilizing suggestions from other StackOverflow questions, have tried using an OPENJSON similar to this,
but it is not returning the results I expected
select * from openjson((select [description] from #OrderHistory)
,'$.deliverySchedule.details[1].candyLimit[1].@type'
)
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
select * from #OrderHistory OH
CROSS APPLY OPENJSON(OH.description)
Returns Key/Value pairs in separate columns, and the Value column still has nested JSON
select * from openjson((select [description] from #OrderHistory)
,'$.deliverySchedule.details[1].candyLimit[1].@type'
)
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
select * from #OrderHistory OH
CROSS APPLY OPENJSON(OH.description)
Returns Key/Value pairs in separate columns, and the Value column still has nested JSON
2
Answers
One way is to chain together some
OPENJSON
calls with explicit schema (fiddle)Arrays are zero based so you need
[0]
not[1]
(if you are specifically interested in the first array element only as seems to be the case from the code you posted) andcandyLimit
is just an object so doesn’t need any index at all.If you’re only interested in flat values (ie. the first array value), you can use JSON_VALUE directly: