3

I have an app that needs to be supplied with configuration data as key value pairs in JSON.

I want to output JSON of key value pairs from a table query.

The table can have different named items and varying quanities of items.

TABLE

ITEMID REPORTID NAME VALUE
1 29 caption Profit by Product
2 29 bgColor #FFFFFF
3 29 showBorder 0
4 29 showsum 0

SQL

select .................   FOR JSON PATH

I'm guessing this needs to use a PIVOT?

Expected JSON

{"caption":"Profit by Product","bgColor":"#FFFFFF","showBorder":"0","showsum":"0"}

Appreciate help anyone can provide.

3 Answers 3

3

Your can do a little String Aggregation (assuming not 2017)

Example

Declare @YourTable Table ([ITEMID] varchar(50),[REPORTID] varchar(50),[NAME] varchar(50),[VALUE] varchar(50))  Insert Into @YourTable Values 
 (1,29,'caption','Profit by Product')
,(2,29,'bgColor','#FFFFFF')
,(3,29,'showBorder','0')
,(4,29,'showsum','0')


Select REPORTID
      ,JSONString =  '{' + Stuff((Select concat(',','"',Name,'":"',value,'"') From @YourTable Where ReportID=A.ReportID For XML Path ('')),1,1,'')  + '}'
 From @YourTable A
 Group by REPORTID

Returns

REPORTID    JSONString
29          {"caption":"Profit by Product","bgColor":"#FFFFFF","showBorder":"0","showsum":"0"}
Sign up to request clarification or add additional context in comments.

1 Comment

Great, +1 from my side. I think it's worth to mention, that using For XML Path (''),TYPE).value('.','nvarchar(max)'),1,1,'') would avoid unescaped XML entities.
2

A pivot query along with FOR JSON PATH should generate the JSON output you expect:

SELECT
    MAX(CASE WHEN NAME = 'caption' THEN VALUE END) AS caption,
    MAX(CASE WHEN NAME = 'bgColor' THEN VALUE END) AS bgColor,
    MAX(CASE WHEN NAME = 'showBorder' THEN VALUE END) AS showBorder,
    MAX(CASE WHEN NAME = 'showsum' THEN VALUE END) AS showsum
FROM yourTable
GROUP BY
    ITEMID
FOR JSON PATH;

enter image description here

Demo

Note that if your table contains more than one ITEMID group, then there would be one JSON record in the output per item.

7 Comments

I should have mentioned that this needs to be flexible and the key value pairs can change / have different number.
This is the best answer of which I know given the sample data you actually showed us. If my answer falls short for a certain use case, then provide data for that case.
I have changed the question, apologies for not being clear.
I don't know of a way to handle your requirement other than by having generic key names, such as key1, key2, etc. Would that be acceptable to you?
There are hundreds of potential keys, so I'm hoping for something flexible rather than using rigid fields.
|
0

I know this is an old post, but having this question myself I wondered if there was another way. And found one - using the quirky update behaviour of SQL server to perform a custom aggregation using the MODIFY_JSON function in SQL 2016:

go
create or alter function getSourceAsJson(@id int) returns nvarchar(max) as
begin
    declare @j nvarchar(max) = '{}'

    select @j = JSON_MODIFY(@j, '$.' + [name], [value]) 
    from SourceTable
    where Id = @id

    return @j
end
go

select dbo.getSourceAsJson(1) as Json

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.