SQL 到 JSON - 将结果分组到 JSON 数组中
SQL to JSON - Grouping Results into JSON Array
我正在尝试提出一个 SQL 解决方案来安排输出以匹配预期的 JSON 格式。
我有一些简单的 SQL 来强调问题的来源;
SELECT TOP 1 'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'work' AS 'telecom.use'
,'phone' AS 'telecom.system'
,'12344556' AS 'telecom.value'
FROM tblCustomer
FOR json path
这将 return JSON 作为;
[
{
"name": {
"family": "Surname",
"given": "Forename, Middle Name",
"prefix": "Title"
},
"birthdate": "2019-02-13T12:06:45.490",
"gender": "F",
"active": "Yes",
"telecom": {
"use": "work",
"system": "phone",
"value": "12344556"
}
}
]
我需要的是将额外的对象添加到 "telecome" 数组中,使其显示为;
[
{
"name": {
"family": "Surname",
"given": "Forename, Middle Name",
"prefix": "Title"
},
"birthdate": "2019-02-13T12:06:45.490",
"gender": "F",
"active": "Yes",
"telecom": {
"use": "work",
"system": "phone",
"value": "12344556"
},
{
"use": "work",
"system": "home",
"value": "12344556"
},
}
]
我错误地认为我可以继续添加到我的 SQL,如下所示;
SELECT TOP 1 'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'work' AS 'telecom.use'
,'phone' AS 'telecom.system'
,'12344556' AS 'telecom.value'
,'home' AS 'telecom.use'
FROM tblCustomer
FOR json path
但是它会按照我的命名缩进嵌套项目;
Property 'telecom.use' cannot be generated in JSON output due to a
conflict with another column name or alias. Use different names and
aliases for each column in SELECT list.
有没有办法用 SQL 处理这种嵌套,或者我是否需要为 JSON 查询创建单独的查询并合并它们?
谢谢
Using @@Version Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64)
Aug 22 2017 17:04:49 Copyright (C) 2017 Microsoft Corporation
Express Edition (64-bit) on Windows Server 2012 R2 Datacenter 6.3
(Build 9600: ) (Hypervisor)
对问题进行小幅修改以使用动态值而不是强制静态成员。
SELECT TOP 1 'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'work' AS 'telecom.use'
,'phone' AS 'telecom.system'
,customerWorkTelephone AS 'telecom.value'
,'home' AS 'telecom.use'
,'phone' AS 'telecom.system'
,customerHomeTelephone AS 'telecom.value'
FROM tblCustomer
FOR json path
"value" 项将从 tblCustomer table 中的列中获取。我已尝试在下面的回复中做好准备,但无法在子查询中获得完全正确的逻辑。
再次感谢
进一步编辑
我有一些 SQL 可以提供我期望的输出,但是我不确定它是否是最好的,我的方法是否不够理想?
SELECT TOP 1 [name.family] = 'Surname'
,[name.given] = 'Forename, Middle Name'
,[name.prefix] = 'Title'
,[birthdate] = GETDATE()
,[gender] = 'F'
,[active] = 'Yes'
,[telecom] = (
SELECT [use] = V.used
,[system] = 'phone'
,[value] = CASE V.used
WHEN 'work'
THEN cu.customerWorkTelephone
WHEN 'home'
THEN cu.customerHomeTelephone
when 'mobile'
then cu.customerMobileTelephone
END
FROM (
VALUES ('work')
,('home')
,('mobile')
) AS V(used)
FOR json path
)
FROM tblCustomer cu
FOR JSON PATH
使用带有一些硬编码行的子选择:
SELECT TOP 1
'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'telecom' = (
SELECT
'work' AS 'use'
,V.system AS 'system'
,'12344556' AS 'value'
FROM
(VALUES
('phone'),
('home')) AS V(system)
FOR JSON PATH)
FROM tblCustomer
FOR JSON PATH
请注意子查询中缺少 telecom.
前缀。
结果(没有 table 参考):
[
{
"name": {
"family": "Surname",
"given": "Forename, Middle Name",
"prefix": "Title"
},
"birthdate": "2019-02-13T12:53:08.400",
"gender": "F",
"active": "Yes",
"telecom": [
{
"use": "work",
"system": "phone",
"value": "12344556"
},
{
"use": "work",
"system": "home",
"value": "12344556"
}
]
}
]
PD:特别是对于 SQL 服务器,我发现使用左侧的别名更具可读性:
SELECT TOP 1
[name.family] = 'Surname',
[name.given] = 'Forename, Middle Name',
[name.prefix] = 'Title',
[birthdate] = GETDATE(),
[gender] = 'F',
[active] = 'Yes',
[telecom] = (
SELECT
[use] = 'work',
[system] = V.system,
[value] = '12344556'
FROM
(VALUES ('phone'), ('home')) AS V(system)
FOR JSON
PATH)
FROM tblCustomer
FOR JSON
PATH
SELECT
EMP.ID,
EMP.NAME,
DEP.NAME
FROM EMPLOYEE EMP INNER JOIN DEPARTMENT DEP ON EMP.DEPID=DEP.DEPID
WHERE EMP.SALARY>1000
FOR JSON PATH
我正在尝试提出一个 SQL 解决方案来安排输出以匹配预期的 JSON 格式。
我有一些简单的 SQL 来强调问题的来源;
SELECT TOP 1 'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'work' AS 'telecom.use'
,'phone' AS 'telecom.system'
,'12344556' AS 'telecom.value'
FROM tblCustomer
FOR json path
这将 return JSON 作为;
[
{
"name": {
"family": "Surname",
"given": "Forename, Middle Name",
"prefix": "Title"
},
"birthdate": "2019-02-13T12:06:45.490",
"gender": "F",
"active": "Yes",
"telecom": {
"use": "work",
"system": "phone",
"value": "12344556"
}
}
]
我需要的是将额外的对象添加到 "telecome" 数组中,使其显示为;
[
{
"name": {
"family": "Surname",
"given": "Forename, Middle Name",
"prefix": "Title"
},
"birthdate": "2019-02-13T12:06:45.490",
"gender": "F",
"active": "Yes",
"telecom": {
"use": "work",
"system": "phone",
"value": "12344556"
},
{
"use": "work",
"system": "home",
"value": "12344556"
},
}
]
我错误地认为我可以继续添加到我的 SQL,如下所示;
SELECT TOP 1 'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'work' AS 'telecom.use'
,'phone' AS 'telecom.system'
,'12344556' AS 'telecom.value'
,'home' AS 'telecom.use'
FROM tblCustomer
FOR json path
但是它会按照我的命名缩进嵌套项目;
Property 'telecom.use' cannot be generated in JSON output due to a conflict with another column name or alias. Use different names and aliases for each column in SELECT list.
有没有办法用 SQL 处理这种嵌套,或者我是否需要为 JSON 查询创建单独的查询并合并它们?
谢谢
Using @@Version Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64) Aug 22 2017 17:04:49 Copyright (C) 2017 Microsoft Corporation Express Edition (64-bit) on Windows Server 2012 R2 Datacenter 6.3 (Build 9600: ) (Hypervisor)
对问题进行小幅修改以使用动态值而不是强制静态成员。
SELECT TOP 1 'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'work' AS 'telecom.use'
,'phone' AS 'telecom.system'
,customerWorkTelephone AS 'telecom.value'
,'home' AS 'telecom.use'
,'phone' AS 'telecom.system'
,customerHomeTelephone AS 'telecom.value'
FROM tblCustomer
FOR json path
"value" 项将从 tblCustomer table 中的列中获取。我已尝试在下面的回复中做好准备,但无法在子查询中获得完全正确的逻辑。
再次感谢
进一步编辑
我有一些 SQL 可以提供我期望的输出,但是我不确定它是否是最好的,我的方法是否不够理想?
SELECT TOP 1 [name.family] = 'Surname'
,[name.given] = 'Forename, Middle Name'
,[name.prefix] = 'Title'
,[birthdate] = GETDATE()
,[gender] = 'F'
,[active] = 'Yes'
,[telecom] = (
SELECT [use] = V.used
,[system] = 'phone'
,[value] = CASE V.used
WHEN 'work'
THEN cu.customerWorkTelephone
WHEN 'home'
THEN cu.customerHomeTelephone
when 'mobile'
then cu.customerMobileTelephone
END
FROM (
VALUES ('work')
,('home')
,('mobile')
) AS V(used)
FOR json path
)
FROM tblCustomer cu
FOR JSON PATH
使用带有一些硬编码行的子选择:
SELECT TOP 1
'Surname' AS 'name.family'
,'Forename, Middle Name' AS 'name.given'
,'Title' AS 'name.prefix'
,getDATE() AS 'birthdate'
,'F' AS 'gender'
,'Yes' AS 'active'
,'telecom' = (
SELECT
'work' AS 'use'
,V.system AS 'system'
,'12344556' AS 'value'
FROM
(VALUES
('phone'),
('home')) AS V(system)
FOR JSON PATH)
FROM tblCustomer
FOR JSON PATH
请注意子查询中缺少 telecom.
前缀。
结果(没有 table 参考):
[
{
"name": {
"family": "Surname",
"given": "Forename, Middle Name",
"prefix": "Title"
},
"birthdate": "2019-02-13T12:53:08.400",
"gender": "F",
"active": "Yes",
"telecom": [
{
"use": "work",
"system": "phone",
"value": "12344556"
},
{
"use": "work",
"system": "home",
"value": "12344556"
}
]
}
]
PD:特别是对于 SQL 服务器,我发现使用左侧的别名更具可读性:
SELECT TOP 1
[name.family] = 'Surname',
[name.given] = 'Forename, Middle Name',
[name.prefix] = 'Title',
[birthdate] = GETDATE(),
[gender] = 'F',
[active] = 'Yes',
[telecom] = (
SELECT
[use] = 'work',
[system] = V.system,
[value] = '12344556'
FROM
(VALUES ('phone'), ('home')) AS V(system)
FOR JSON
PATH)
FROM tblCustomer
FOR JSON
PATH
SELECT
EMP.ID,
EMP.NAME,
DEP.NAME
FROM EMPLOYEE EMP INNER JOIN DEPARTMENT DEP ON EMP.DEPID=DEP.DEPID
WHERE EMP.SALARY>1000
FOR JSON PATH