Я пытаюсь написать запрос к UNION
объектам из двух связанных таблиц и вернуть результаты Azure SQL Server в виде объектов JSON.У меня возникла проблема с запросом, которую я не могу решить.
Когда я запрашиваю таблицу entity
со списком подобъектов grades
, используя опцию FOR JSON PATH
для возврата объектов в формате JSON, я получаю ожидаемый результат.
Запрос
SELECT
entity.name AS name,
(
SELECT
grade_translation.name,
grade_translation.short_name
FROM
entity_grades,
grade,
grade_translation,
language
WHERE
entity.id = entity_grades.entity_id
AND entity_grades.grade_id = grade.id
AND grade.id = grade_translation.non_translated_id
AND grade_translation.language_id = language.id
AND language.short_name = 'en'
ORDER BY
entity_grades.[order]
FOR JSON PATH
) AS grades
FROM entity
LEFT JOIN entity_translation ON entity_translation.non_translated_id = entity.id
LEFT JOIN language ON language.id = entity_translation.language_id
WHERE language.short_name = 'en'
FOR JSON PATH
Результат
[{
"name": "Test Entity 1",
"about": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Porta lorem mollis aliquam ut porttitor leo. Lacus sed viverra tellus in hac habitasse.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Integer malesuada nunc vel risus commodo. Neque aliquam vestibulum morbi blandit cursus risus.",
"grades": [{
"name": "Grade 9",
"short_name": "9"
}, {
"name": "Grade 10",
"short_name": "10"
}, {
"name": "Grade 11",
"short_name": "11"
}, {
"name": "Grade 12",
"short_name": "12"
}]
}, {
"name": "Test Entity 2",
"about": "Blah blah blah"
}]
То же самое касается объектовкоторые не имеют переводов.
Запрос (сущности без переводов)
SELECT
entity.name AS name,
(
SELECT
grade_translation.name,
grade_translation.short_name
FROM
entity_grades,
grade,
grade_translation,
language
WHERE
entity.id = entity_grades.entity_id
AND entity_grades.grade_id = grade.id
AND grade.id = grade_translation.non_translated_id
AND grade_translation.language_id = language.id
AND language.short_name = 'en'
ORDER BY
entity_grades.[order]
FOR JSON PATH
) AS grades
FROM entity
LEFT JOIN entity_translation ON entity_translation.non_translated_id = entity.id
LEFT JOIN language ON language.id = entity_translation.language_id
WHERE entity.id NOT IN (SELECT DISTINCT entity_translation.non_translated_id FROM entity_translation)
FOR JSON PATH
Результат
[{
"name": "Test Entity 3"
}]
Нокогда я объединяю эти два запроса вместе, я получаю массив grades
, который экранирован.
Запрос (UNION)
SELECT
entity.name AS name,
(
SELECT
grade_translation.name,
grade_translation.short_name
FROM
entity_grades,
grade,
grade_translation,
language
WHERE
entity.id = entity_grades.entity_id
AND entity_grades.grade_id = grade.id
AND grade.id = grade_translation.non_translated_id
AND grade_translation.language_id = language.id
AND language.short_name = 'en'
ORDER BY
entity_grades.[order]
FOR JSON PATH
) AS grades
FROM entity
LEFT JOIN entity_translation ON entity_translation.non_translated_id = entity.id
LEFT JOIN language ON language.id = entity_translation.language_id
WHERE language.short_name = 'en'
UNION
SELECT
entity.name AS name,
(
SELECT
grade_translation.name,
grade_translation.short_name
FROM
entity_grades,
grade,
grade_translation,
language
WHERE
entity.id = entity_grades.entity_id
AND entity_grades.grade_id = grade.id
AND grade.id = grade_translation.non_translated_id
AND grade_translation.language_id = language.id
AND language.short_name = 'en'
ORDER BY
entity_grades.[order]
FOR JSON PATH
) AS grades
FROM entity
LEFT JOIN entity_translation ON entity_translation.non_translated_id = entity.id
LEFT JOIN language ON language.id = entity_translation.language_id
WHERE entity.id NOT IN (SELECT DISTINCT entity_translation.non_translated_id FROM entity_translation)
FOR JSON PATH
Результат
[{
"name": "Test Entity 1",
"about": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Porta lorem mollis aliquam ut porttitor leo. Lacus sed viverra tellus in hac habitasse.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Integer malesuada nunc vel risus commodo. Neque aliquam vestibulum morbi blandit cursus risus.",
"grades": "[{\"name\":\"Grade 9\",\"short_name\":\"9\"},{\"name\":\"Grade 10\",\"short_name\":\"10\"},{\"name\":\"Grade 11\",\"short_name\":\"11\"},{\"name\":\"Grade 12\",\"short_name\":\"12\"},{\"name\":\"Adult\",\"short_name\":\"AD\"}]"
}, {
"name": "Test Entity 2",
"about": "Blah blah blah"
}, {
"name": "Test Entity 3"
}]
Я попытался обернуть внутреннюю SELECT
операторы с JSON_QUERY
, как предложено в следующей ссылке, но это не имело никакого эффекта.
Ref: Как мне не допустить, чтобы FOR JSON PATH избегал результатов запроса?
Запрос с помощью функции обтекания JSON_QUERY
SELECT
entity.name AS name,
JSON_QUERY((
SELECT
grade_translation.name,
grade_translation.short_name
FROM
entity_grades,
grade,
grade_translation,
language
WHERE
entity.id = entity_grades.entity_id
AND entity_grades.grade_id = grade.id
AND grade.id = grade_translation.non_translated_id
AND grade_translation.language_id = language.id
AND language.short_name = 'en'
ORDER BY
entity_grades.[order]
FOR JSON PATH
)) AS grades
FROM entity
LEFT JOIN entity_translation ON entity_translation.non_translated_id = entity.id
LEFT JOIN language ON language.id = entity_translation.language_id
WHERE language.short_name = 'en'
UNION
SELECT
entity.name AS name,
JSON_QUERY((
SELECT
grade_translation.name,
grade_translation.short_name
FROM
entity_grades,
grade,
grade_translation,
language
WHERE
entity.id = entity_grades.entity_id
AND entity_grades.grade_id = grade.id
AND grade.id = grade_translation.non_translated_id
AND grade_translation.language_id = language.id
AND language.short_name = 'en'
ORDER BY
entity_grades.[order]
FOR JSON PATH
)) AS grades
FROM entity
LEFT JOIN entity_translation ON entity_translation.non_translated_id = entity.id
LEFT JOIN language ON language.id = entity_translation.language_id
WHERE entity.id NOT IN (SELECT DISTINCT entity_translation.non_translated_id FROM entity_translation)
FOR JSON PATH
Есть ли что-нибудь еще, что я могу попытаться вернуть в правильном формате JSON из этого стиля запроса?Может кто-нибудь объяснить, является ли это особенность или ошибка?