Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server:使用group by将列查询到JSON对象_Sql_Json_Sql Server_Tsql - Fatal编程技术网

SQL Server:使用group by将列查询到JSON对象

SQL Server:使用group by将列查询到JSON对象,sql,json,sql-server,tsql,Sql,Json,Sql Server,Tsql,我有一个有3列的表,我想查询该表,这样结果将是一个JSON对象 示例数据如下所示: CREATE TABLE #Test (ValueV INT, KEYS NVARCHAR (100), ID INT) INSERT INTO #Test VALUES (1, N'ChangeAdress 19 - 21', 200), (1, N'ChangeAdress 20 - 22', 200), (1, N'ChangeAdress 22 - 24', 3

我有一个有3列的表,我想查询该表,这样结果将是一个JSON对象

示例数据如下所示:

 CREATE TABLE #Test (ValueV INT, KEYS NVARCHAR (100), ID INT) 

 INSERT INTO #Test 
 VALUES (1, N'ChangeAdress 19 - 21', 200),
        (1, N'ChangeAdress 20 - 22', 200),
        (1, N'ChangeAdress 22 - 24', 300),
        (1, N'ChangeAdress 23 - 25', 300),
        (2, N'ChangeAdress 24 - 26', 400),
        (2, N'ChangeAdress 25 - 27', 400),
        (3, N'ChangeAdress 26 - 28', 400),
        (3, N'ChangeAdress 27 - 29', 400)

 SELECT * FROM #Test
我的查询尝试:

 SELECT ID, Keys, ValueV
 FROM #Test  
 GROUP BY ID, keys, ValueV
 FOR JSON AUTO
但它返回1个JSON“行”。我想要的是每组一行。组在此ID、值组合。我对JSON对象几乎没有经验,这些对象可能在这个查询中是可见的,因此希望能得到帮助

所需的输出,但作为每行的JSON:

 --------------------------------------------------
|200, 1, ChangeAdress 19 - 21, ChangeAdress 20 - 22|
|300, 1, ChangeAdress 22 - 24, ChangeAdress 23 - 25|
|400, 2, ChangeAdress 24 - 26, ChangeAdress 25 - 27|
|400, 3, ChangeAdress 26 - 28, ChangeAdress 27 - 29|
提前谢谢

试试这个:

SELECT (SELECT [ID], [Keys], [ValueV]  FOR JSON PATH)
FROM #Test 
GROUP BY ID, keys, ValueV
或者这个:

SELECT (SELECT [ID], [Keys], [ValueV]  FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
FROM #Test 
GROUP BY ID, keys, ValueV

这在SQL Server 2017中有效,在SQL Server 2017中可以使用STRING_AGG,但相当笨拙。我不确定有没有更优雅的方式

SELECT (
    SELECT 
       ID, 
       ValueV, 
       Keys = JSON_QUERY('["' + STRING_AGG(STRING_ESCAPE(Keys, 'json'), '","') + '"]')
    FOR JSON PATH
)
FROM #Test 
GROUP BY ID, ValueV
对于SQL Server 2016,它没有STRING_AGG或STRING_ESCAPE:

SELECT (
    SELECT ID, ValueV, Keys = JSON_QUERY(REPLACE(REPLACE(
        (
            SELECT Keys 
            FROM #Test t2 WHERE t2.ID = t1.ID AND t2.ValueV = t1.ValueV 
            FOR JSON PATH
        ),
        '{"Keys":', ''),
        '}', ''))
    FOR JSON PATH
)
FROM #Test t1
GROUP BY ID, ValueV
甚至不那么优雅,但你可以得到你能得到的。至少我们没有连接FOR XML…

我的两分钱:

有趣的是,您需要有效的单个JSON行,而不是一个JSON字符串。无论如何,这里有一些备选答案,尽管公认的答案是最好的

-- 100% hardcoded yourself. Pre SQL Server 2016 
SELECT '[{"ID":' + convert(nvarchar(4),T1.[ID]) + ',"ValueV":' + convert(nvarchar(4),T1.[ValueV]) + ',"Keys":["' + T1.[Keys] + '","' + T2.[Keys] + '"]}]' AS [keys]
FROM #Test AS T1 INNER JOIN #Test T2 ON t2.ID = t1.ID AND t2.ValueV = t1.ValueV AND t2.keys > t1.keys 
或:

或:


请注意,JSON本身不是一个对象,只是一个命名值对字符串,有效的JavaScript只是一个子集。不过,如果您想要一个嵌套的JavaScript对象,那么它看起来完全不同,如果JS是您的预期数据目标,我在这里假设。JSON函数非常适合快速提取数据进行传输,但是当您需要嵌套输出或将数据集分组为值数组而不是对象数组时,它可能会变得非常棘手。就个人而言,因为它是一个字符串,对于更复杂的东西,我只是自己构建它。希望这是一个不同的想法

如果有任何一个具有相同类型的用例,则发布此消息

SELECT [t].[ID], 
(SELECT [t1].[KEYS], [t1].[ValueV] FROM @Test t1 WHERE t1.[ID] = [t].id FOR JSON PATH ) a
FROM @Test AS [t]
GROUP BY [t].[ID]

输出不清楚。您现在得到的不是JSON。你想要类似于{ID:200,ValueV:1,KEYS:[ChangeAdress 19-21,ChangeAdress 20-22]}的东西吗?@jeroenmoster如果这是常规的JSON格式,那么是的。我对JSON对象不太熟悉,很抱歉。谢谢你提出的好问题。我也遇到了这个问题,非常感谢。这指向了正确的方向。但是,在本例中,我希望返回4行。您的查询返回8。感谢您添加一些选项。我已经有一段时间没有发布这篇文章了,但你还是付出了一些努力,太棒了!我的问题解决的唯一原因是,您可以使用json格式的select格式再次选择,最后使用group by避免重复行或使用distinct。如果您希望在单个json中获得结果,您该怎么办?
-- This is a lot cleaner for an array of values in pairs. Again using OPENJSON to output your desired result.  
select 
'[' + [Value] + ']' FROM OPENJSON(
(select T1.[ID], T1.[ValueV], JSON_MODIFY(JSON_MODIFY('[]','append lax $',t0.keys),'append lax $',t1.keys) as keys
FROM #Test AS T0 inner join #Test as t1
on  t0.ID = t1.ID AND t0.ValueV = t1.ValueV AND t0.keys < t1.keys
FOR JSON path))
SELECT [t].[ID], 
(SELECT [t1].[KEYS], [t1].[ValueV] FROM @Test t1 WHERE t1.[ID] = [t].id FOR JSON PATH ) a
FROM @Test AS [t]
GROUP BY [t].[ID]