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「行」を返します。私が欲しいのは、グループごとに1行です。ここにあるグループ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|
前もって感謝します!
これは機能します(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
と連結していません...
これを試して:
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
私の2セント:
興味深いのは、単一の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
または:
-- 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))
または:
-- 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))
JSON自体はオブジェクトではなく、名前付きの値のペアの文字列、有効なJavaScriptでありながらサブセットであることに注意してください。たとえば、ネストされたJavaScriptオブジェクトが必要な場合は、JSが目的のデータ宛先である場合、完全に異なります。私はここを想定しています)。 JSON関数は、データをすばやく転送して転送するのに最適ですが、ネストされた出力が必要な場合や、オブジェクトではなく値の配列のデータセットをグループ化する場合は、かなり扱いにくい場合があります。個人的には文字列なので、より複雑なものについては自分で作成します。それが別の見方であることを願っています。