JSON auto 的意外结果

Unexpected result with JSON auto

我低于 3 table 和示例数据:

员工、地址、州

/****** Object:  Table [AzureSearch].[Address]    Script Date: 11/2/2021 2:16:55 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [AzureSearch].[Address](
    [EmployeeId] [int] NULL,
    [Address] [nvarchar](60) NULL,
    [City] [nvarchar](30) NULL
) ON [PRIMARY]
GO
/****** Object:  Table [AzureSearch].[Employee]    Script Date: 11/2/2021 2:16:55 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [AzureSearch].[Employee](
    [EmployeeId] [int] NOT NULL,
    [FirstName] [nvarchar](200) NOT NULL,
    [LastName] [nvarchar](200) NOT NULL
) ON [PRIMARY]
GO
/****** Object:  Table [AzureSearch].[States]    Script Date: 11/2/2021 2:16:55 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [AzureSearch].[States](
    [City] [varchar](50) NULL,
    [StateName] [varchar](50) NULL
) ON [PRIMARY]
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (1, N'4350 Minute Dr.', N'Newport Hills')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (2, N'7559 Worth Ct.', N'Renton')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (3, N'2137 Birchwood Dr', N'Redmond')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (4, N'5678 Lakeview Blvd.', N'Minneapolis')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (5, N'9435 Breck Court', N'Bellevue')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (6, N'5670 Bel Air Dr.', N'Renton')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (7, N'1873 Lion Circle', N'Bothell')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (7, N'3858 Vista Diablo', N'Issaquah')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (8, N'4912 La Vuelta', N'Bothell')
GO
INSERT [AzureSearch].[Address] ([EmployeeId], [Address], [City]) VALUES (8, N'4039 Elkwood Dr.', N'Ballard')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (1, N'Ken', N'Sánchez')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (2, N'Terri', N'Duffy')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (3, N'Roberto', N'Tamburello')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (4, N'Rob', N'Walters')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (5, N'Gail', N'Erickson')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (6, N'Jossef', N'Goldberg')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (7, N'Osarumwense', N'Agbonile')
GO
INSERT [AzureSearch].[Employee] ([EmployeeId], [FirstName], [LastName]) VALUES (8, N'Karl', N'Xie')
GO
INSERT [AzureSearch].[States] ([City], [StateName]) VALUES (N'Bothell', N'Washington')
GO
INSERT [AzureSearch].[States] ([City], [StateName]) VALUES (N'Ballard', N'Utah')
GO

当我 运行 下面查询时,我在一个 JSON 对象

中得到 JSON 详细信息
SELECT e.EmployeeId
        ,(
            SELECT a.Address
                ,a.City
            --  ,s.StateName AS StateName
            FROM AzureSearch.[Address] AS a
            --  ,AzureSearch.States AS s
            WHERE a.EmployeeId = e.employeeId
            --  AND a.City = s.City
            FOR json auto
            ) AS AddressDetails
FROM azuresearch.Employee AS e
 WHERE e.EmployeeId = 8

AddressDetails 列中的结果:

[
    {
     "Address": "4912 La Vuelta",
     "City": "Bothell"
    },
    {
        "Address": "4039 Elkwood Dr.",
        "City": "Ballard"
    }
]

但是如果您取消注释上面 SQL 查询中的注释行以包含来自 States table 的列,我得到的结果如下:

为什么 StateName 详细信息进入数组?

我可以通过调整查询将其与地址和城市详细信息一起放在外面吗?

FOR JSON AUTO 根据 SELECT 语句的结构自动格式化 FOR JSON 子句的输出。 documentation 说明:当您指定 AUTO 选项时,JSON 输出的格式将根据 SELECT 列表中列的顺序及其来源自动确定table秒。您无法更改此格式

语句连接 tables(尽管它使用旧式 JOIN 语法),因此 States table 中的列生成为嵌套 [=28] 的属性=] 数组使用 table 别名作为此嵌套数组的名称。

在你的情况下,更好的选择是 FOR JSON PATH:

SELECT 
   e.EmployeeId,
   (
        SELECT 
            a.Address
           ,a.City
           ,s.StateName
        FROM 
            [Address] AS a
           ,[States] AS s
        WHERE 
            a.EmployeeId = e.employeeId
            AND a.City = s.City
        FOR JSON PATH
   ) AS AddressDetails
FROM [Employee] AS e
WHERE e.EmployeeId = 8

结果:

EmployeeId AddressDetails
8          [
           {"Address":"4912 La Vuelta","City":"Bothell","StateName":"Washington"},
           {"Address":"4039 Elkwood Dr.","City":"Ballard","StateName":"Utah"}
           ]