我正在尝试提出一种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
它将返回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
但是它将按照我的命名缩进嵌套项目;
由于与另一个列名或别名冲突,无法在JSON输出中生成属性’telecom.use’。SELECT列表中的每一列使用不同的名称和别名。
有没有一种方法可以使用SQL处理这种嵌套,还是需要为JSON查询创建单独的并将其合并?
谢谢
使用@@ Version Microsoft SQL Server 2017(RTM)-14.0.1000.169(X64)2017年8月22日17:04:49版权所有(C)2017 Windows Server 2012 R2 Datacenter 6.3(Build 9600)上的Microsoft Corporation Express Edition(64位) :)(管理程序)
对问题进行小的编辑,以使用动态值而不是强制静态成员。
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
“值”项将从tblCustomer表中的列中获取。我试图弥补下面的响应,但无法在子查询中获得完全正确的逻辑。
再次感谢
进一步编辑
我有一些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.,子查询中缺少前缀。
telecom.
结果(无表参考):
[ { "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 Server,我发现使用左侧的别名更易读:
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