如何使SQL表的字段值成为SQL中JSON对象的键?

问题描述 投票:3回答:1

我一直在尝试以我想要的格式从我的数据库中获取JSON对象,因此我运行了以下sql查询:

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;

以及查询结果如下:

{
  "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"
}

但实际上我想要的是不同的。 JSON对象应如下所示:

{
  "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"
        },
}

那么,我怎么能得到这个JSON对象?

sql json sql-server sql-server-json
1个回答
1
投票

据我所知,你不能用select ... for json创建带有变量键名的json。

但是,如果你不介意使用变量并且你正在使用Sql Server 2017(否则你不能使用json-modify的动态密钥),你可以这样做:

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

select
    @a = json_modify(
        @a,
        concat('$.', p.key_code),
        json_query((select p.name, p.[date], p.descr for json path, without_array_wrapper))
    )
from projects as p

select @a

db fiddle demo

如果您使用的是早期版本的Sql Server,您可以使用您可以找到的任何聚合方法将其聚合(为了简单起见,我使用了string_agg):

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

您可能还会考虑使用string_escape来防止错误,以防您的密钥包含特殊字符:

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

db fiddle demo

© www.soinside.com 2019 - 2024. All rights reserved.