4

I'm trying to create object with dynamic key and value with SQL Server. Currently I have the following query result:

[ 
    { "Name": "Ashley", "type": "human" },
    { "Name": "Dori", "type": "cat" }
]

and I am looking to build this:

[ { "Human": "Ashley" }, { "Cat": "Dori" } ]

PS: I'm not sure if it's even possible, but I have no ideas left.

4
  • 1
    Do you know all the possible options up front? You can't create dynamic keys without dynamic SQL, but you could include every possible key name in a static query. Sample input would help Commented Jul 12, 2021 at 21:01
  • Thanks, good to know that at least I need to create dynamic SQL and yes they are 4 possible keys Commented Jul 12, 2021 at 21:04
  • 2
    Note that putting data in your JSON names is as inconvenient to consume as it is to create. Commented Jul 12, 2021 at 21:18
  • I have a special case, that's why I need it that way, but maybe I had to just return it like this and do it on my own on the backend Commented Jul 12, 2021 at 21:22

2 Answers 2

4

If you know every possible combination up front, you can specify them in CASE expressions like this

SELECT
    Human = CASE WHEN t.[type] = 'human' THEN t.Name END,
    Cat =   CASE WHEN t.[type] = 'cat'   THEN t.Name END
-- more options
FROM YourTable t
FOR JSON PATH;

If you don't know what the possible options are, you will need dynamic SQL.

Try to keep a clear head about which part is static and which is dynamic. Use PRINT @sql; to test.

DECLARE @sql nvarchar(max) = '
SELECT
' + (
    SELECT STRING_AGG(CAST(
'    ' + typeCol + ' = CASE WHEN t.[Type] = ' + typeStr + ' THEN t.Name END'
        AS nvarchar(max)), ',
')
    FROM (
        SELECT DISTINCT
           typeCol = QUOTENAME(UPPER(LEFT(t.[type], 1)) + SUBSTRING(t.[type], 2, LEN(t.[type]))),
           typeStr = QUOTENAME(t.[type], '''')
        FROM YourTable t
    )
) + '
FROM YourTable t
FOR JSON PATH;
';

PRINT @sql; --for testing

EXEC sp_executesql @sql;  -- add parameters if necessary
Sign up to request clarification or add additional context in comments.

1 Comment

Both answers makes a lot of sense for me, thanks! I was looking for these solutions for hours now. :)
1

I would like to add another solution, perhaps for different cases.

In case you already have a generated JSON and you want to transform it, for example:

[
    {
        "key": "key1",
        "value": "value1"
    },
    {
        "key": "key2",
        "value": "value2"
    },
    {
        "key": "key3",
        "value": "value3"
    }
]

You can apply this sql script to transform it:

SET @json = REPLACE(@json, '","', '":"')
SET @json = REPLACE(@json, '"key":', '')
SET @json = REPLACE(@json, '"value":', '')
SET @json = REPLACE(@json, '{', '')
SET @json = REPLACE(@json, '}', '')
SET @json = REPLACE(@json, '[', '{')
SET @json = REPLACE(@json, ']', '}')

for the example, the result would transform into this:

{
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
}

1 Comment

I have a perfectly valid key/value pair like this "\"{[\"key\",":"][}\":" now what's going to happen?or

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.