从SQL表中选择JSON值,然后将结果转换为单个JSON对象

问题描述

搜索过很多东西,但似乎找不到像我想做的那样遥远的东西,但是我确定这不是什么新鲜事物,而且我很确定自己正在荷马时刻。

给出一个包含JSON列的表:

DECLARE @Table TABLE
(
    [VALUE] nvarchar(max) NOT NULL
);

该列中的值可以是任何有效的JSON OBJECT,我没有控制数据,只是它的有效性,并且所有条目都具有相同的结构,但我不知道。这很重要,因为它确实限制了某些可用选项。

INSERT INTO @Table
VALUES ( N'{"X":"2020-01-01","Y":"27"}' ),( N'{"X":"2020-02-01","Y":"48"}' ),( N'{"X":"2020-04-01","Y":"63"}' ),( N'{"X":"2020-05-01","Y":"75"}' ),( N'{"X":"2020-06-01","Y":"32"}' ),( N'{"X":"2020-08-01","Y":"12"}' ),( N'{"X":"2020-09-01","Y":"96"}' ),( N'{"X":"2020-10-01","Y":"105"}' );

INSERT INTO @Table
VALUES ( N'{"Monkey":"1","Elephant":"9"}' ),( N'{"Monkey":"2","Elephant":"8"}' ),( N'{"Monkey":"3","Elephant":"7"}' ),( N'{"Monkey":"4","Elephant":"6"}' ),( N'{"Monkey":"5","Elephant":"5"}' ),( N'{"Monkey":"6","Elephant":"4"}' ),( N'{"Monkey":"7","Elephant":"3"}' ),( N'{"Monkey":"8","Elephant":"2"}' );

我需要能够将所有行的内容转换为一个JSON Document

[{
    "VALUES": [
        { "X": "2020-01-01","Y": "27" },{ "X": "2020-02-01","Y": "48" },{ "X": "2020-04-01","Y": "63" },{ "X": "2020-05-01","Y": "75" },{ "X": "2020-06-01","Y": "32" },{ "X": "2020-08-01","Y": "12" },{ "X": "2020-09-01","Y": "96" },{ "X": "2020-10-01","Y": "105" }
    ]
}]

鉴于我的SELECT语句,我至少可以将数据查询到表结果中:

SELECT [VALUES] = JSON_QUERY( [VALUE],N'$' )
FROM @Table;

VALUES
{"X":"2020-01-01","Y":"27"}
{"X":"2020-02-01","Y":"48"}
{"X":"2020-04-01","Y":"63"}
{"X":"2020-05-01","Y":"75"}
{"X":"2020-06-01","Y":"32"}
{"X":"2020-08-01","Y":"12"}
{"X":"2020-09-01","Y":"96"}
{"X":"2020-10-01","Y":"105"}

但是当我将结果转换为JSON时,它就会出错:

SELECT [VALUES] = JSON_QUERY( [VALUE],N'$' )
FROM @Table
FOR JSON PATH;

[
    { "VALUES": { "X": "2020-01-01","Y": "27" } },{ "VALUES": { "X": "2020-02-01","Y": "48" } },{ "VALUES": { "X": "2020-04-01","Y": "63" } },{ "VALUES": { "X": "2020-05-01","Y": "75" } },{ "VALUES": { "X": "2020-06-01","Y": "32" } },{ "VALUES": { "X": "2020-08-01","Y": "12" } },{ "VALUES": { "X": "2020-09-01","Y": "96" } },{ "VALUES": { "X": "2020-10-01","Y": "105" } }
]

在我的一生中,我似乎无法接受最后的排序,希望另一双更聪明的眼睛会发现我的错误

解决方法

如果可以保证该表包含有效的JSON,那么下面是一个快速而肮脏的解决方案。没有使用任何Microsoft SQL Server JSON支持,但是使用了一些字符串连接...

-- SQL SERVER 2016
select '[{ "VALUES":['
    +  stuff((  select ',' + t.[VALUE]
                from @Table t
                for xml path(''),type).value('.','nvarchar(max)'),1,'')
    + ']}]';


-- SQL SERVER 2017 and later
select '[{ "VALUES":[' + string_agg(t.VALUE,',') + ']}]' from @Table t;
第一组样本数据的

Formatted结果:

[
  {
    "VALUES": [
      {
        "X": "2020-01-01","Y": "27"
      },{
        "X": "2020-02-01","Y": "48"
      },{
        "X": "2020-04-01","Y": "63"
      },{
        "X": "2020-05-01","Y": "75"
      },{
        "X": "2020-06-01","Y": "32"
      },{
        "X": "2020-08-01","Y": "12"
      },{
        "X": "2020-09-01","Y": "96"
      },{
        "X": "2020-10-01","Y": "105"
      }
    ]
  }
]