如何在SQL中将多个表输出转换为子JSON

时间:2019-07-09 11:55:16

标签: sql json sql-server sql-server-2016

我一直试图在SQL中从三个表创建一个json对象

主表/实体是“订单”,其id为addressId

,并且进一步的地址表具有countryId和stateId,这是指

状态表和国家/地区表

orderTable

    Id  AddressId   Status
    1     1         Processed

AddressTable

Id countryId  stateId FirstName  LastName
1    5            7     John       cena


countryTable

Id   Name
5     usa


StateTable

Id   Name
7     DC

输出应显示如下

{
  "firstName": "John",
  "lastName": "cena",
  "Country" : {
                 "name": "usa",
                 "id" : "5"
              },
  "States" :  {
                    "name": "DC",
                    "id" : "7"
            }

}

我尝试使用此查询并获得相似的结果,但我想从json中删除[] []数组对象容器

[      // I want to remove this 
{

  "FirstName": "Steve",

  "LastName": "Gates",



     "country": 
 [       // I want to remove this 
      {

                  "name": "usa",
                 "id" : "5"
              }
       ],  // I want to remove this 

"states" :
         [  // I want to remove this 
           {
                    "name": "DC",
                    "id" : "7"
            }


     ]  // I want to remove this 

根据Microsoft的博客,我们可以使用

FOR JSON PATH, WITHOUT_ARRAY_WRAPPER

但是如果我使用this,那么它不包括国家和州作为单独的子对象 所以我使用了“ FOR JSON AUTO”,它给了我想要的输出,但是它还为每个json对象添加了方形片

这是我的查询

 Select ord.*, (Select *  from Address ad Left outer join Country country on country.Id = ad.CountryId
 Left outer join State sp on sp.Id = ad.StateId  where ad.Id = ord.AddressId  FOR JSON AUTO) as AddressJson
 , (Select *  from Address ad Left outer join Country country on country.Id = ad.CountryId
 Left outer join State sp on sp.Id = ad.StateId  where ad.Id = ord.AddressId1  FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) as AddressJson2
 from [order] ord ) 

1 个答案:

答案 0 :(得分:1)

在您的示例中,我认为不需要使用所有子查询。我只是使用联接和点分隔的别名来获得所需的输出。

Format Query Results as JSON with FOR JSON

  

在PATH模式下,您可以使用点语法-例如,   'Item.UnitPrice'-设置嵌套输出的格式。

然后添加WITHOUT_ARRAY_WRAPPER选项以删除括号。

这是一个可行的示例:

DECLARE @AddressTable TABLE
    (
        [Id] INT
      , [countryId] INT
      , [stateId] INT
      , [FirstName] NVARCHAR(100)
      , [LastName] NVARCHAR(100)
    );

DECLARE @countryTable TABLE
    (
        [Id] INT
      , [name] NVARCHAR(100)
    );

DECLARE @stateTable TABLE
    (
        [Id] INT
      , [name] NVARCHAR(100)
    );

INSERT INTO @AddressTable (
                              [Id]
                            , [countryId]
                            , [stateId]
                            , [FirstName]
                            , [LastName]
                          )
VALUES ( 1, 5, 7, N'John', N'cena' );

INSERT INTO @countryTable (
                              [Id]
                            , [name]
                          )
VALUES ( 5, N'usa' );

INSERT INTO @stateTable (
                            [Id]
                          , [name]
                        )
VALUES ( 7, N'DC' );

SELECT     [a].[FirstName]
         , [a].[LastName]
         , [ct].[name] AS 'Country.name' --dot-separated alias
         , [ct].[Id] AS 'Country.Id'
         , [st].[name] AS 'States.name'
         , [st].[Id] AS 'States.Id'
FROM       @AddressTable [a]
INNER JOIN @stateTable [st]
    ON [st].[Id] = [a].[stateId]
INNER JOIN @countryTable [ct]
    ON [ct].[Id] = [a].[countryId]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;

这将为您提供以下输出:

{
  "FirstName": "John",
  "LastName": "cena",
  "Country": {
    "name": "usa",
    "Id": 5
  },
  "States": {
    "name": "DC",
    "Id": 7
  }
}