1

I want to extract the following json into a table like below. There may be multiple entries under the LIABILITY section so each one will generate a new row. The metrics under the RESPONSE/SUMMARY section will repeat for each one of the LIABILITY entries. I'm not sure how to extract the SUMMARY metric - Right now, I want to designate the NAME (e.g. 'Number of books') I want under DATASET, and pull the corresponding value (e.g., 27)

I am using Microsoft SQL Server

Report ID    |   File ID   | Number of books
123456           ABC01       27
123456           ABC02       27
 {
 "RESPONSE": {
    "@ReportIdentifier": "123456",
    "@ReportFirstIssuedDate": "2021-02-12",
    },

   "LIABILITY": [
      {
        "@LiabilityID": "TRADE001",
        "@BorrowerID": "Borrower01",
        "@FileID": "ABC01"
      }, 

      {
        "@LiabilityID": "TRADE001",
        "@BorrowerID": "Borrower01",
        "@FileID": "ABC02"
      }
                      ], 
   
   "SUMMARY": {
      "@BorrowerID": "Borrower01",
      "@_Name": "Attributes",
      "_DATA_SET": [
        {
          "@_Name": "Number of books",
          "@_Value": "27"
        },
        {
          "@_Name": "Average age of borrow",
          "@_Value": "35"
        },
        {
          "@_Name": "Number of messages",
          "@_Value": "4"
        }
1
  • You need to say what kind of a database you're using. Commented Mar 2, 2022 at 0:49

1 Answer 1

2

It's not going to be pretty and you'd probably be better off parsing this json in some kind of backend code, e.g. C#, Python, JavaScript, whatever.

Now that you're warned, you're going to want to use a couple of JSON related functions in SQL:

  • JSON_VALUE - extract a scalar value from the json object (e.g. the report identifier)
  • OPENJSON - open the json object/array as if it was a table

We end up with:

SELECT JSON_VALUE(json, '$.RESPONSE."@ReportIdentifier"') AS ReportID
     , JSON_VALUE(Liability.value, '$."@FileID"') AS FileID
     , Summary.Value AS NumberOfBooks
 FROM so
CROSS
APPLY OPENJSON(json, '$.LIABILITY') AS Liability
CROSS
APPLY OPENJSON(json, '$.SUMMARY."_DATA_SET"') 
      WITH
      (
         Name NVARCHAR(25) '$."@_Name"'
       , Value NVARCHAR(25) '$."@_Value"'
      ) AS Summary
WHERE Summary.name = 'Number of books'

Here you see @ReportIdentifier can be extracted directly from your json object using a straightforward path. Since you want a row per each liability array element, we have to extract that using OPENJSON and then use JSON_VALUE to extract @FileID from each of the elements. Finally with the summary nested object we can't simply extract value because this is a dictionary and we just want the number of books. I don't know whether Number of Books dict entry is always first in your data set, so I opted for translating the whole array into a table and then filter only for the rows where the name is 'Number of Books'.

Here's a working demo on dbfiddle

Sign up to request clarification or add additional context in comments.

Comments

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.