7

If you have a simple table like:

Id Name Age  
1  Saeed 32  
2  John  28  
3  David 34

Then you can create a JSON using For XML in SQL Server just like:

select '{ name : "' + Name + '", age : ' + age + ' }'
from People
where Id = 1
for xml path('')

This is easy, because columns are known beforehand. However, I'm stuck at creating JSON from an EAV table. For example, if the table is:

Id EntityId Key    Value
1  1        Name   Saeed
2  1        Age    32
3  1        Gender Male
4  1        Key1   Value1
5  1        Key2   Value2

How can I create this JSON?

{ Name: "Saeed", Age: 32, Gender: "Male", Key1: "Value1", Key2: "Value2" }

From this query:

select *
from PeopleEav
where EntityId = 1

Please note that the number of keys is variable (it's an EAV table).

5
  • 3
    display formatting does not belong to back end. Do it in the client. Commented Sep 4, 2013 at 4:58
  • 1
    Thanks for that precious info dear @RemusRusanu. Sometimes academic rules are not in action ;) Commented Sep 4, 2013 at 5:00
  • A couple people have tacked this with stored procedures, like this and this. Commented Sep 4, 2013 at 5:05
  • 1
    Sometimes academic rules are not in action indeed. I just wonder why are they out of action in this case? Commented Sep 4, 2013 at 5:23
  • You mention FOR XML but you don't actually use it in the query. What's that about? Commented Sep 4, 2013 at 6:07

2 Answers 2

5

Try this one -

DECLARE @PeopleEav TABLE
(
      Id INT IDENTITY(1,1)
    , EntityId INT
    , [Key] VARCHAR(30)
    , Value VARCHAR(100)
)

INSERT INTO @PeopleEav (EntityId, [Key], Value)
VALUES
    (1, 'Name',   'Saeed'),
    (1, 'Age',    '32'),
    (1, 'Gender', 'Male'),
    (1, 'Key1',   'Value1'),
    (1, 'Key2',   'Value2')

SELECT 
      t.EntityId
    , JSON = STUFF((
        SELECT ', ' + [Key] + ': "' + Value + '"'
        FROM @PeopleEav t2
        WHERE t2.EntityId = t2.EntityId
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '{ ') + ' }'                  
FROM (
    SELECT DISTINCT EntityId
    FROM @PeopleEav
) t
--WHERE EntityId = 1

Output -

EntityId    JSON
----------- --------------------------------------------------------------------------------------------
1           { Name: "Saeed", Age: "32", Gender: "Male", Key1: "Value1", Key2: "Value2" }
0

If you have Sql Server 2016 you can use FOR JSON. You can also use existing CLR libraries such as JsonSelect or Json4Sql.

1
  • A working example with FOR JSON for provided input would be good.
    – Oleksandr
    Commented Feb 15, 2019 at 14:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.