Как разобрать столбец JSON в таблицу с помощью TSQL

Я пытаюсь открыть строку JSON, и каждый ключ должен быть отдельным столбцом. Столбец JSON находится в таблице метаданных с ключом и полиморфным идентификатором.

Как разобрать столбец JSON в таблицу с помощью TSQL

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

Как разобрать столбец JSON в таблицу с помощью TSQL

Я могу анализировать каждый ключ один за другим с помощью json_query, но я вижу, что есть вызов функции openjson, которая может анализировать всю строку, но я не знаю, как ее использовать, так как пример из документации применяет функцию к набору значение вместо столбца из таблицы. Есть ли более простой способ разобрать строку JSON, чем использовать json_query?

Пожалуйста, указывайте дату в текстовом виде, а не в виде изображения. Это значительно повысит шансы получить ответ.

Alex Kudryashev 28.03.2019 01:32
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
5
1
5 514
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Пожалуйста, попробуйте это:

SELECT p.RelatedPolymorphId,p.[BrandPresent],p.[OneImage],p.[UPCPresent],p.[ModelNumberPresent],p.[TitlePresent],p.[DescriptionPresent],p.[Feature1Present]
FROM (SELECT v.RelatedPolymorphId,v.Value AS [JsonValue] FROM [YourTableName] v) a
CROSS APPLY OPENJSON(a.JsonValue) j
PIVOT(MAX(j.[value]) FOR j.[key] IN ([BrandPresent],[OneImage],[UPCPresent],[ModelNumberPresent],[TitlePresent],[DescriptionPresent],[Feature1Present])) p
;

Нет, PIVOT здесь неправильный подход. Лучше использовать OPENJSON в связи с предложением WITH. Помимо скорости, преимуществом является тип, который вы можете разместить в каждом производном столбце. Кроме того, можно легко установить псевдоним столбца в WITH. И очень часто нам нужно глубже погрузиться во вложенный JSON. Это был бы беспорядок без WITH ... См. Мой ответ для примера

Shnugo 28.03.2019 11:11

Почему это "неправильный подход"? Это просто другое, что может быть полезно в некоторых случаях.

Vitaly Borisov 28.03.2019 23:08

Нет, во-первых, эта сводка заставит вас возвращать все с одним и тем же типом, могут быть неожиданные результаты из-за агрегации, это огромные накладные расходы, и она не допускает иерархии Json.

Shnugo 28.03.2019 23:21

OPENJSON возвращает NVARCHAR — результаты и агрегация всегда соответствуют ожиданиям. Я вижу, ты фанат слова "Нет".

Vitaly Borisov 28.03.2019 23:25

Нет, ?, предложение With позволяет указать тип. Делайте, что хотите, на мой взгляд, это неправильный подход... Happy Coding

Shnugo 28.03.2019 23:30

Вы можете попробовать следующий подход, используя предложения OPENJSON() и WITH (для указания столбцов и их типов). Без предложения WITHOPENJSON возвращает три столбца — key, value и type каждой пары {key: value}.

Вход

CREATE TABLE #Table (
   RelatedPolimorphicId int,
   [Key] nvarchar(50),
   [Value] varchar(max)
)
INSERT INTO #Table
   (RelatedPolimorphicId, [Key], [Value])
VALUES
   (23, N'ContentStats', N'{"BrandPresent": true, "OneImage": true, "UPCPresenet": true, "ModelNumberPresent": true, "TitlePresent": true, "DescriptionPresent": true, "Feature1Present": true}')

Заявление

SELECT 
   t.RelatedPolimorphicId,
   j.*
FROM #Table t
CROSS APPLY (
   SELECT * 
   FROM OPENJSON(t.[Value])
   WITH (
       BrandPresent varchar(10) '$.BrandPresent',
       OneImage varchar(10) '$.OneImage',
       UPCPresenet varchar(10) '$.UPCPresenet',
       ModelNumberPresent varchar(10) '$.ModelNumberPresent',
       TitlePresent varchar(10) '$.TitlePresent',
       DescriptionPresent varchar(10) '$.TitlePresent',
       Feature1Present varchar(10) '$.Feature1Present'
   )
) j

Выход

RelatedPolimorphicId    BrandPresent    OneImage    UPCPresenet ModelNumberPresent  TitlePresent    DescriptionPresent  Feature1Present
23                      true            true        true        true              true              true            true

Это правильно в принципе, но слишком сложно (подвыбор не требуется). Еще плюс с моей стороны.

Shnugo 28.03.2019 11:06
Ответ принят как подходящий

я бы попробовал такой подход

SELECT t.RelatedPolimorphicId
      ,t.[Key] 
      ,A.*
FROM YourMetaDataTable t
CROSS APPLY OPENJSON(t.[Value]) 
WITH (
     BrandPresent BIT
    ,OneImage BIT
    ,UPCPresenet BIT
    ,ModelNumberPresent BIT
    ,TitlePresent BIT
    ,DescriptionPresent BIT
    ,Feature1Present BIT
) A;

OPENJSON в сочетании с предложением WITH предлагает хороший, чистый и типобезопасный (!) подход к чтению вашего JSON. Я бы использовал BIT, потому что true и false будут переведены неявно.

Что, если, скажем, ModelNumberPresent — это массив, и вы также хотите «взорвать» его?

CutePoison 19.10.2020 12:51

@CutePoison Просто добавьте еще один вызов openjson(A.ModelNumberPresent) B и изучите результат (измените BIT на NVARCHAR(MAX) AS Json и добавьте B.* в список выбора).

Shnugo 19.10.2020 12:54

Если хотите, можете добавить этот ответ в stackoverflow.com/questions/64424626/…

CutePoison 19.10.2020 13:04

Спасибо всем за ответ. @shnugo, в вашем решении с openjson решение по-прежнему должно перечислять все ключи, которые я хотел разобрать, я решил это с помощью JSON_query, более простого решения, но проблема в том, что мне нужно разобрать более 40 ключей, что неэффективно. чтобы перечислить их один за другим. Я искал функцию, которая может анализировать столбец JSON без указания каждого ключа в строке JSON.

решение с json_query

Это не ответ, а скорее комментарий... Ну, один принцип с SQL-Server таков: движок не должен иметь структуру набора результатов заранее. Поскольку вы хотите использовать свои внутренние JSON в качестве имен столбцов, вы должны указать движку, что делать... Ваше решение (ссылка) ни в коем случае не проще или более эффективным. Мое решение возвращает именно тот ожидаемый результат, который вы указали в своем вопросе. Если вам нужно что-то еще, пожалуйста, не меняйте этот вопрос, а закройте его, приняв один из ответов, и начните новый вопрос. В противном случае погуглите "вопрос-хамелеон". Удачного кодирования...

Shnugo 28.03.2019 19:11

Другие вопросы по теме