简体   繁体   中英

How to make the field values of a SQL table to be the keys of JSON object in SQL?

I have been trying to get a JSON object from my DB in the format that I wanted it so I ran the following sql query:

SELECT PROJECTS.key_code AS CODE, PROJECTS.name AS Name,
         PROJECTS.date AS Date, PROJECTS.descr AS Description
         FROM PROJECTS LEFT JOIN ACCESS
         ON PROJECTS.key_code = ACCESS.key_code
         WHERE ACCESS.Ukey_code = '5d8hd5' FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;

and the result of the query as follow:

{
  "Code": "h5P93G",
  "Name": "Project1 test name",
  "Date": "2017-09-03",
  "Description": "This is a test description 1"
 },
  "Code": "KYJ482",
  "Name": "Project2 test name",
  "Date": "2018-10-25",
  "Description": "This is a test description 2"
}

but actually what I want is different. The JSON object should look like:

{
  "h5P93G": {
          "Name": "Project1 test name",
          "Date": "2017-09-03",
          "Description": "This is a test description 1"
        },
  "KYJ482": {
          "Name": "Project2 test name",
          "Date": "2018-10-25",
          "Description": "This is a test description 2"
        },
}

So, how I could get this JSON object?

As far as I know, you cannot really create JSON with variable key names with select... for json .

However, if you don't mind using variables and you're using SQL Server 2017 (otherwise you cannot use dynamic keys for json-modify ), you can do it like this:

declare @a nvarchar(max) = '{}'

select
    @a = json_modify(
        @a,
        concat('$."', p.key_code, '"'), /*This line fixed by @Zhorov*/
        json_query((select p.name, p.[date], p.descr for json path, without_array_wrapper))
    )
from projects as p

select @a

db fiddle demo

If you're using earlier editions of SQL Server, you can just aggregate it with any aggregation method you can find (I've used string_agg just for simplicity here):

select
    concat('{', string_agg(
        concat('"',p.key_code,'":',p.data),
        ','
    ), '}')
from (
    select
        p.key_code,
        (select p.name, p.[date], p.descr for json path, without_array_wrapper) as data
    from projects as p
) as p

db fiddle demo

You might also consider using string_escape to prevent errors in case your keys can contain special characters:

select
    ...
        concat('"',string_escape(p.key_code,'json'),'":',p.data),
        ','
    ...

db fiddle demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM