I have a table with a record that has JSON content and it is an array with no name. Sample data looks like this:
carId | carType | parts |
---|---|---|
Z003 | Company | [{"Value":"New","Type":"Brakes","Code":"D"},{"Value":"Upgraded","Type":"Doors","Code":"E1"}] |
Z003 | Company | [{"Value":null,"Type":"Brakes","Code":"D"},{"Value":null,"Type":"Doors","Code":"E1"}] |
Z003 | Company | [{"Value":"USed","Type":"Brakes","Code":"D"},{"Value":"New","Type":"Tires","Code":"G7"}] |
There are actually about 20 to 30 classes within the array but i have shown only 2 for simplicity. So for each record I am trying to extract certain classes with certain attributes into their own field. Like so:
carId | carType | BrakesCode | DoorsValue |
---|---|---|---|
Z003 | Company | D | Upgraded |
Z003 | Company | D | null |
Z003 | Company | D | null |
I have tried numerous queries and have not succeeded. Here is my latest:
SELECT carId, carType, JSON_VALUE( JSON_QUERY(parts,'$[0]'),'$[0].Code')
FROM [Assets].[dbo].[Cars]
Which results in:
JSON text is not properly formatted. Unexpected character '.' is found at position 4.
I know I have to insert a WHERE somewhere so I can match the Type=Brakes but am unsure where that goes. Any help appreciated.
we can use OPENJSON to parses our JSON text and returns objects and properties from the JSON input as rows and columns, then we use MAX()
With CASE
to get the expected data,
with cte as (
SELECT carId, carType, Code, Type, value
FROM Cars
CROSS APPLY OPENJSON([parts], '$')
WITH (
Code NVARCHAR(50) '$.Code',
Type NVARCHAR(50) '$.Type',
value NVARCHAR(50) '$.Value'
)
)
select carId, carType,
MAX(case when Type = 'Brakes' then Code end) as BrakesCode,
MAX(case when Type = 'Doors' then [Value] end) as DoorsValue
from cte
where Type in ('Brakes', 'Doors')
group by carId, carType
Result :
carId carType BrakesCode DoorsValue
Z001 Company D Upgraded
Z002 Company D null
Z003 Company D null