1

I have a table like :

ID Args
1 {"requester":"Alexandre", "recipients":[{"first":"John", "last":"Smith"}, {"first":"Elisa", "last":"Martin"}, {....}, {"first":"Michael", "last":"Dubois"}]}
2 {"requester":"Martin", "recipients":[{"first":"Jean", "last":"Dupont"}, {"first":"Elisa", "last":"Martin"}]}
... ...
n {"requester":"Jean", "recipients":[{"first":"Jacques", "last":"Dupont"}, {"first":"Elisa", "last":"Gardner"}, {....}, {"first":"Michael", "last":"Dupont"}]}

What I would like to have:

ID Requester Recipientfirst
1 Alexandre John
1 Alexandre Elisa
1 Alexandre ...
1 Alexandre Michael
2 Martin Jean
... ... ...

PS: The number of recipients varies.

My tests:

select id, JSON_VALUE(args, '$.requester') requester, JSON_VALUE(args, '$.recipients[0].first') recipient
from table

But the idea would be to iterate here on the number of recipients (here only 0)

I also achieve to do this :

DECLARE @json nvarchar(max)
select @json = args from table
print @json

SELECT first
FROM OPENJSON( @json, '$.recipients' )
WITH ([first] NVARCHAR(25) '$.first');

And it allows to have the firstname list of the first line only.

Does anyone know how to get the desired result?

1
  • 2
    Tag the question with the RDBMS you're using. I'm assuming SQL Server given the NVARCHAR, but why make anyone assume. Commented Mar 1, 2022 at 10:15

2 Answers 2

2

Two levels of OPENJSON should do it:

SELECT t.id, j1.requester, j2.first_name
FROM t
CROSS APPLY OPENJSON(t.args) WITH (   
    requester NVARCHAR(100) '$.requester',  
    recipients NVARCHAR(MAX) AS JSON  
) AS j1
CROSS APPLY OPENJSON(j1.recipients) WITH (
    first_name NVARCHAR(100) '$.first'
) AS j2
Sign up to request clarification or add additional context in comments.

Comments

2

My brute force approach would be to use CROSS APPLY to open up different parts of the JSON string...

SELECT
  *
FROM
  example
CROSS APPLY
(
  SELECT *
    FROM OPENJSON(example.json)
         WITH (
           [requester] NVARCHAR(25) '$.requester'
         )
)
  json_requester
CROSS APPLY
(
  SELECT *
    FROM OPENJSON(example.json, '$.recipients')
         WITH (
           [recipient_first] NVARCHAR(25) '$.first',
           [recipient_last]  NVARCHAR(25) '$.last'
         )
)
  json_recipient

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=b79a6ecb271d4322487ede013d54c8e0

1 Comment

Solid, but seems unnecessarily complicated given that we only need one value from the root object. SELECT id, JSON_VALUE(json, '$.requester') AS Requester, [first] AS [Recipient first] FROM example CROSS APPLY OPENJSON(json, '$.recipients') WITH ([first] NVARCHAR(25)) should suffice.

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.