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

Пожалуйста, попробуйте это:
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 ... См. Мой ответ для примера
Почему это "неправильный подход"? Это просто другое, что может быть полезно в некоторых случаях.
Нет, во-первых, эта сводка заставит вас возвращать все с одним и тем же типом, могут быть неожиданные результаты из-за агрегации, это огромные накладные расходы, и она не допускает иерархии Json.
OPENJSON возвращает NVARCHAR — результаты и агрегация всегда соответствуют ожиданиям. Я вижу, ты фанат слова "Нет".
Нет, ?, предложение With позволяет указать тип. Делайте, что хотите, на мой взгляд, это неправильный подход... Happy Coding
Вы можете попробовать следующий подход, используя предложения 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
Это правильно в принципе, но слишком сложно (подвыбор не требуется). Еще плюс с моей стороны.
я бы попробовал такой подход
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 Просто добавьте еще один вызов openjson(A.ModelNumberPresent) B и изучите результат (измените BIT на NVARCHAR(MAX) AS Json и добавьте B.* в список выбора).
Если хотите, можете добавить этот ответ в stackoverflow.com/questions/64424626/…
Спасибо всем за ответ. @shnugo, в вашем решении с openjson решение по-прежнему должно перечислять все ключи, которые я хотел разобрать, я решил это с помощью JSON_query, более простого решения, но проблема в том, что мне нужно разобрать более 40 ключей, что неэффективно. чтобы перечислить их один за другим. Я искал функцию, которая может анализировать столбец JSON без указания каждого ключа в строке JSON.
Это не ответ, а скорее комментарий... Ну, один принцип с SQL-Server таков: движок не должен иметь структуру набора результатов заранее. Поскольку вы хотите использовать свои внутренние JSON в качестве имен столбцов, вы должны указать движку, что делать... Ваше решение (ссылка) ни в коем случае не проще или более эффективным. Мое решение возвращает именно тот ожидаемый результат, который вы указали в своем вопросе. Если вам нужно что-то еще, пожалуйста, не меняйте этот вопрос, а закройте его, приняв один из ответов, и начните новый вопрос. В противном случае погуглите "вопрос-хамелеон". Удачного кодирования...
Пожалуйста, указывайте дату в текстовом виде, а не в виде изображения. Это значительно повысит шансы получить ответ.