Преобразование массива пар ключ-значение в json в таблицу в SQL Server - PullRequest
0 голосов
/ 05 июня 2019

У меня есть таблица, в которой один столбец является идентификатором некоторого исполняемого кода, а другой столбец - это массив пар ключей-значений имени переданных параметров и значений, отформатированных следующим образом

executionId|params                                                           |

200001     |[{"key":"name","value":"john"},{"key":"surname","value":"smith"}]|

где количество передаваемых параметров произвольно, и я хочу вывести его в виде таблицы.

Я пытался с этим запросом

SELECT 
   t.executionId,
   j.*
FROM #tmpTransac t
CROSS APPLY (
   SELECT * 
   FROM OPENJSON(t.[params])
   ) j

Но вывод, который я получаю, это

executionId|key|value
1992013     0   {"key":"name","value":"john"}
1992013     1   {"key":"surname","value":"smith"}   

и я ожидал что-то вроде

executionId| name |surname
1992013    | john |smith

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Мое предложение использует OPENJSON, включая предложение WITH и PIVOT

- A таблица макетов

DECLARE @tbl TABLE(executionId INT,params NVARCHAR(MAX))
INSERT INTO @tbl VALUES(200001,'[{"key":"name","value":"john"},{"key":"surname","value":"smith"}]');

- запрос

SELECT p.*
FROM
(
    SELECT t.executionId
          ,A.[key] AS ParamKey
          ,A.[value] AS ParamValue
    FROM @tbl t
    CROSS APPLY OPENJSON(t.params) WITH([key] NVARCHAR(MAX),[value] NVARCHAR(MAX)) A
) t
PIVOT(MAX(ParamValue) FOR ParamKey IN([Name],Surname)) p;

Идея вкратце:

Немного удивляет, что элементы JSON имеют те же имена, что и столбцы, возвращаемые OPENJSON.но предложение WITH будет искать эти имена в JSON , поэтому будет возвращен список типа

name       john
surname    smith

, чтобы получить рядом вы можете использовать PIVOT или условное агрегирование -

0 голосов
/ 05 июня 2019

Вам нужно развернуть данные, так как они находятся в 2 отдельных строках JSON внутри вашего большего значения:

SELECT V.executionId,
       MAX(CASE N.[key] WHEN 'name' THEN N.[value] END) AS [name],
       MAX(CASE N.[key] WHEN 'surname' THEN N.[value] END) AS [surname]
FROM (VALUES(200001,'[{"key":"name","value":"john"},{"key":"surname","value":"smith"}]'))V(executionId, params)
     CROSS APPLY OPENJSON(V.params) OJ
     CROSS APPLY OPENJSON(OJ.[value]) 
                 WITH ([key] varchar(50) '$.key',
                       [value] varchar(100) '$.value') N
GROUP BY V.executionId;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...