0

I have stored data in sql server as Json format, which as give below. I would like to retrieve it as normal string value. I have tried JSON_VALUE but json may or may not have more than one child, so it should retrieve all the values.

Input

TableA

   ID Education
   -------------------------------------------------------------------------------------
    1  {"Education": {"Record":[{"SLSubject":"MICRO ECONOMICS","Score":"77","Grade":"A"}]}}
    2  {"Education": {"Record":[{"SLSubject":"Math","Score":"89","Grade":"A"},{"SLSubject":"eng","Score":"88","Grade":"B"},{"SLSubject":"tam","Score":"33","Grade":"C"}]}}
    3  {"Education":{"Record":[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]}}

Expected Output

ID Education
-------------------------------------------------------------------------------------
1  MICRO ECONOMICS - 77 - A
2  Math - 88 - B \n end - 88 - B \n Tam - 33 - C
3  subject 1 - 87- A \n subject 2 - 67- B \n subject 3 - 45- C \n subject 1 - 87- D \n

Query (which is working for one child)

SELECT ID, JSON_VALUE(Education,'$.Education.Record[0].SLSubject')
FROM TableA

Actual Result

ID Education
-------------------------------------------------------------------------------------
1  MICRO ECONOMICS - 77 - A
2  Math - 88 - B
3  subject 1 - 87- A

Sample JSON:

{"Education":{"Record":[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]}}
2
  • Why do you not want a normalised data set? Commented Sep 17, 2019 at 15:40
  • We will send report to the user for validation. To send that report we need to show education record of the candidate. Commented Sep 17, 2019 at 15:43

1 Answer 1

2

You need to use OPENJSON and treat your data as a dataset, JSON_VALUE is for returning a scalar value. This'll likely be what you really want:

SELECT YT.ID,
       OJ.SLSubject,
       OJ.Score,
       OJ.Grade
FROM (VALUES(1,N'[{"SLSubject":"MICRO ECONOMICS","Score":"77","Grade":"A"}]'),
            (2,N'[{"SLSubject":"Math","Score":"89","Grade":"A"},{"SLSubject":"eng","Score":"88","Grade":"B"},{"SLSubject":"tam","Score":"33","Grade":"C"}]'),
            (3,N'[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]'))YT(ID,Education) 
     CROSS APPLY OPENJSON(YT.Education) 
                 WITH (SLSubject varchar(20),
                       Score int,
                       Grade char(1)) OJ;

Seems the OP wants this?

SELECT YT.ID,
       STRING_AGG(CONCAT(OJ.SLSubject, ' - ', OJ.Score, ' - ', OJ.Grade),' \n ') WITHIN GROUP (ORDER BY OJ.SLSubject) AS Education
FROM (VALUES(1,N'[{"SLSubject":"MICRO ECONOMICS","Score":"77","Grade":"A"}]'),
            (2,N'[{"SLSubject":"Math","Score":"89","Grade":"A"},{"SLSubject":"eng","Score":"88","Grade":"B"},{"SLSubject":"tam","Score":"33","Grade":"C"}]'),
            (3,N'[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]'))YT(ID,Education) 
     CROSS APPLY OPENJSON(YT.Education) 
                 WITH (SLSubject varchar(20),
                       Score int,
                       Grade char(1)) OJ
GROUP BY YT.ID;

DB<>Fiddle

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

9 Comments

Thanks but i wanted in single column as Subject, Score and Grade as combined.
Subject, Score, and Grade are on a single row @VigneshKumarA . Do you mean "column"? A row is the horizontal part of the datagrid (in this case, will contain a single value for ID, Subject, Score, and Grade). A Column is the vertical part of the datagrid, so will contain all the values for a specific data piece (such as Score).
Use CONCAT: CONCAT(OJ.SLSubject,'-',OJ.Score,'-',OJ.Grade)@VigneshKumarA
But ID:2 will have more than one rows for education know
So you want to aggregate the columns and rows? Like that @VigneshKumarA?
|

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.