2

I have a table with lots of rows like:

ID     |     Attributes
1      |     {"Rank":1, "LoadLocation": London, "Driver":Tom}
2      |     {"Rank":2, "LoadLocation": Southampton, "Driver":Dick}
3      |     {"Rank":3, "DischargeLocation": Stratford}

There isn't a template for the JSON - it's a dumping ground for any number of attributes of the ID rows.

For use in a join I'd like to get these into a table this:

ID     |     Attribute Name     |  Attribute Value 
1      |     'Rank'             |   1
1      |     'LoadLocation'     |   'London'
1      |     'Driver'           |   'Tom'
2      |     'Rank'             |    2
2      |     'LoadLocation'     |   'Southampton'
2      |     'Driver'           |   'Dick'
3      |     'Rank'             |    3 
3      |     'DischargeLocation'|   'Stratford'

I can see that I probably need to be using OpenJSON, but also that for that I likely need to know the explicit structure. I don't know the structure, even to the point of each row having a different numbe of attributes.

Any help gratefully received!

5
  • I assume you're using SQL Server 2016+? What have you trued so far? Commented Oct 7, 2019 at 14:07
  • Can you add a JSON string so I can parse it on my machine Commented Oct 7, 2019 at 14:09
  • It's a pretty straight forward parsing, just want to make sure I can test it Commented Oct 7, 2019 at 14:09
  • @Kelevra The OP has provided sample data. Commented Oct 7, 2019 at 14:10
  • @Lamu - yes, I figure it'd be easier to cope with the denormalised table in a join than a large table whose column names I wouldn't know (as anything could be in the JSON string) Commented Oct 7, 2019 at 14:16

1 Answer 1

6

If you have sql-server-2016 and above, you can use OPENJSON with CROSS APPLY

DECLARE @TestData TABLE (ID INT, Attributes VARCHAR(500))
INSERT INTO @TestData VALUES
(1 ,'{"Rank":1, "LoadLocation": "London", "Driver":"Tom"}'),
(2 ,'{"Rank":2, "LoadLocation": "Southampton", "Driver":"Dick"}'),
(3 ,'{"Rank":3, "DischargeLocation": "Stratford"}')


SELECT T.ID, X.[key] AS [Attribute Name], X.value AS [Attribute Value] 
FROM @TestData T
    CROSS APPLY (SELECT * FROM OPENJSON(T.Attributes)) AS X

Result:

ID          Attribute Name       Attribute Value    
----------- -------------------- -------------------
1           Rank                 1
1           LoadLocation         London
1           Driver               Tom
2           Rank                 2
2           LoadLocation         Southampton
2           Driver               Dick
3           Rank                 3
3           DischargeLocation    Stratford
Sign up to request clarification or add additional context in comments.

1 Comment

Amazing I can definitely move on with this - thanks very much

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.