web-dev-qa-db-ja.com

SQL Server 2016 JSON:オブジェクトの配列ではなく文字列の配列を選択します

私はSQLServerのJSONを初めて使用し、文字列の単純な配列を返す方法を理解できません。

DECLARE @T TABLE ([value] NVARCHAR(MAX))

INSERT INTO @T ([value]) VALUES ('foo')
INSERT INTO @T ([value]) VALUES ('bar')
INSERT INTO @T ([value]) VALUES ('test')
INSERT INTO @T ([value]) VALUES ('ok')

SELECT [value]
FROM @T
FOR JSON PATH

これにより、オブジェクトの配列が返されます。

[{"value":"foo"},{"value":"bar"},{"value":"test"},{"value":"ok"}]

私はそれを返したいです:

["foo","bar","test","ok"]

これもできますか?

15
nokturnal

AdventureWorks 2016 CTP3 JSONサンプルでは、​​key:valueペアの配列をクリーンアップし、配列od values:を作成できる関数を見つけることができます。

DROP FUNCTION IF EXISTS dbo.ufnToRawJsonArray
GO
CREATE FUNCTION
[dbo].[ufnToRawJsonArray](@json nvarchar(max), @key nvarchar(400)) returns nvarchar(max)
AS BEGIN
       declare @new nvarchar(max) = replace(@json, CONCAT('},{"', @key,'":'),',')
       return '[' + substring(@new, 1 + (LEN(@key)+5), LEN(@new) -2 - (LEN(@key)+5)) + ']'
END

SELECT FOR JSON式の結果を@jsonパラメーターとして指定し、削除するキーの名前を2番目のパラメーターとして指定するだけです。おそらく次のようなものです:

select dbo.ufnToRawJsonArray( (SELECT value FROM mytable for json path), 'value')
6
Jovan MSFT

SQL2017では、jsonの代わりにSTRING_AGGを使用します。この関数は、値のコンマ区切りリストを生成するのに最適です。

https://docs.Microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql

SELECT town, STRING_AGG (email, ';') AS emails 
FROM dbo.Employee 
GROUP BY town;
4
Roman Polunin

ルイ・バオとローマの答えに基づいて:

declare @t table ([value] nvarchar(max))

insert into @t ([value]) values ('foo')
insert into @t ([value]) values ('bar')
insert into @t ([value]) values ('test')
insert into @t ([value]) values ('ok')

SELECT
    JSON_QUERY((SELECT CONCAT('["',STRING_AGG([value], '","'),'"]') FROM @t)) As MuhArray
    OtherValue,
    AnotherValue
FROM MyTableOValues
FOR JSON PATH

これは、単純な値のJSON有効な配列を作成し、それをプロパティMuhArrayに割り当てています。これからのJSON出力は次のようになります。

[{
  MuhArray: ["foo", "bar", "test", "ok"],
  OtherValue: "Value",
  AnotherValue: "AnotherValue"
}]

ここで、OtherValueAnotherValueは、テーブルにある対応する値を受け取ります。少し手を加えることで、これを選択リストのサブクエリとしてではなく、メインクエリ本体の単純な結合として作成することもできます。私の見解では、選択リストでサブクエリを使用すると、distinctキーワードが不要になります。

2
RobotOptimist

これで始められるはずです。 2016には、JSONを操作する方法がいくつかあります。このメソッドは、JSON文字列を定義し、そこから値を引き出し、XMLトリックを使用して複数の行を1つの行にまとめます。

DECLARE @T TABLE ([value] NVARCHAR(MAX))

INSERT INTO @T ([value])
VALUES ('foo')

INSERT INTO @T ([value])
VALUES ('bar')

INSERT INTO @T ([value])
VALUES ('test')

INSERT INTO @T ([value])
VALUES ('ok')

DECLARE @JSON NVARCHAR(MAX) = (
        SELECT *
        FROM @T
        FOR JSON PATH
        );

WITH cte
AS (
    SELECT *
    FROM OPENJSON(@json) WITH (NAME VARCHAR(10) '$.value')
    )
SELECT QUOTENAME(left(names, LEN(names) - 1) )AS names
FROM (
    SELECT DISTINCT (
            SELECT QUOTENAME(NAME,'"') + ',' AS [text()]
            FROM cte
            FOR XML PATH('')
            ) names
    FROM cte
    ) x
1
dfundako

ローマの答えの上に構築する:

declare @t table ([value] nvarchar(max))

insert into @t ([value]) values ('foo')
insert into @t ([value]) values ('bar')
insert into @t ([value]) values ('test')
insert into @t ([value]) values ('ok')

select concat('[', string_agg(concat('"', [value], '"'), ','), ']')
from @t

出力:

["foo","bar","test","ok"]

1
Louie Bao