J'ai une table avec 3 colonnes, je veux interroger cette table de telle sorte que le résultat sera un objet JSON.
Les exemples de données ressemblent à ceci:
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
Ma tentative de requête:
SELECT ID, Keys, ValueV
FROM #Test
GROUP BY ID, keys, ValueV
FOR JSON AUTO
Mais cela retourne 1 'ligne' JSON. Ce que je veux, c'est une ligne par groupe. Le groupe est ici ID, combinaison de valeurs. J'ai peu d'expérience avec les objets JSON (ce qui est probablement visible à partir de cette requête), une aide serait donc la bienvenue.
La sortie souhaitée (mais ensuite en tant que JSON par ligne):
--------------------------------------------------
|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|
Merci d'avance!
Cela fonctionne (dans SQL Server 2017, où STRING_AGG
est disponible), mais est assez maladroit. Je ne suis pas sûr qu'il n'y ait pas de manière plus élégante.
SELECT (
SELECT
ID,
ValueV,
Keys = JSON_QUERY('["' + STRING_AGG(STRING_ESCAPE(Keys, 'json'), '","') + '"]')
FOR JSON PATH
)
FROM #Test
GROUP BY ID, ValueV
Pour SQL Server 2016 (qui n'a pas de STRING_AGG
ou STRING_ESCAPE
d'ailleurs):
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
Encore moins élégant, mais vous prenez ce que vous pouvez obtenir. Au moins, nous ne sommes pas en concaténation avec FOR XML
...
Essaye ça:
SELECT (SELECT [ID], [Keys], [ValueV] FOR JSON PATH)
FROM #Test
GROUP BY ID, keys, ValueV
ou ca:
SELECT (SELECT [ID], [Keys], [ValueV] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
FROM #Test
GROUP BY ID, keys, ValueV
Mes deux centimes:
Il est intéressant de noter que vous voulez des lignes JSON individuelles valides et non une seule chaîne JSON. Quoi qu’il en soit, voici quelques réponses alternatives, bien que la réponse acceptée soit la meilleure.
-- 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
Ou:
-- Use the OPENJSON to output your results as a dataset and not just a single row. I've removed the escape character back slashes to match the accepted answers output
SELECT
'[' + REPLACE((REPLACE((REPLACE([value], '\','')),':"[',':[')),']"}',']}') + ']'
FROM OPENJSON(
(SELECT T1.[ID],T1.[ValueV], '["' + 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
FOR JSON PATH))
Ou:
-- 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))
Notez simplement que JSON n’est pas un objet, mais simplement une chaîne de paires de valeurs nommées, un JavaScript valide, mais un sous-ensemble néanmoins, il est complètement différent lorsque vous souhaitez par exemple un objet Javascript imbriqué (si JS est la destination de vos données, Je suppose ici). La fonction JSON est idéale pour extraire rapidement des données à transférer, mais lorsque vous souhaitez une sortie imbriquée ou un groupe de données pour un tableau de valeurs et non d'objets, cela peut devenir assez délicat. Personnellement, comme c'est une chaîne, pour des choses plus compliquées, je la construis moi-même. J'espère que c'est une prise différente.