SQL Server选择json,列名作为键,列的唯一值作为列表值

6vl6ewon  于 2022-11-26  发布在  SQL Server
关注(0)|答案(1)|浏览(128)

对于这样的SQL表
| A列|B栏|
| - -|- -|
| × ×|年|
| × ×|兹兹|
| 响|年|
我想检索如下所示的JSON结果

{"Column A": ["Xxx", "Rrr"], 
 "Column B": ["Yyyyy", "zzzz"]}

每列的唯一/相异值应该是作为值添加到JSON键的数组元素。
编辑:备注:SQL Server版本早于2017。
编辑二:
1.应选择表中每列不同值
1.应将选定的非重复值转换为列表。
1.所有列名都应转换为JSON键,列表值应转换为JSON值。

4sup72z8

4sup72z81#

您可以根据需要采用this SO answer

SELECT "Column A" = JSON_QUERY('["'+STUFF((SELECT DISTINCT CONCAT('","',STRING_ESCAPE("Column A",'json'))  
                                             FROM  mytable
                                              FOR XML PATH ('')),1,3,'')+'"]'),
       "Column B" = JSON_QUERY('["'+STUFF((SELECT DISTINCT CONCAT('","',STRING_ESCAPE("Column B",'json'))  
                                             FROM  mytable
                                              FOR XML PATH ('')),1,3,'')+'"]')
   FOR JSON PATH, Without_Array_Wrapper

这样就得到了
| JSON格式|
| - -|
| {“A列”:[“Rrr”,“Xxx”],“B列”:[“Yyyy”,“zzzz”]}|
另请在this db<>fiddle(SQL Server 2016)中查看它的实际应用。
详细解释,由内而外:

  • STRING_ESCAPE确保所选值被正确转义为有效的JSON值。
  • FOR XML PATH将内部查询的结果作为XML而不是行集返回。
  • DISTINCT确保每个元素只有一次。
  • CONCAT连接逗号和双引号。
  • STUFF删除由CONCAT添加的不必要的前导逗号。
  • 添加外部双引号和括号。
  • JSON_QUERY会从建构的JSON字串产生对象。
  • 最后,外部的FOR JSON PATH将构造的列连接到一个JSON中。

请参见this db<>fiddle中的各个步骤。
您还可以使用动态SQL(如this SO answer中所示)为表中的所有列自动执行此操作:

DECLARE @sql VARCHAR(max) = ''
DECLARE @tablename as VARCHAR(255) = 'mytable'

SELECT @sql = @sql + ',[' + c.name + '] = (SELECT JSON_QUERY(''["''+STUFF((SELECT DISTINCT concat(''","'',STRING_ESCAPE([' + c.name + '],''json''))  
                                             FROM  ' + t.name + '
                                              FOR XML PATH ('''')),1,3,'''')+''"]''))' 
  FROM sys.columns c
  JOIN sys.tables t on c.object_id = t.object_id
 WHERE t.name = @tablename
SELECT @sql = 'SELECT ' + STUFF(@sql, 1, 1, '') + ' FOR JSON PATH, Without_Array_Wrapper'
  
EXEC (@sql)

如需具有五个来源数据行的范例,请参阅this db<>fiddle

相关问题