我试图将来自两个相关表的对象一起写到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
语句,但这没有效果。
参考:How do I keep FOR JSON PATH from escaping query results?
使用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吗?有人可以解释这是功能还是错误?
答案 0 :(得分:0)
我通过完全消除UNION解决了这一问题。在这种情况下,这就像向第一个查询添加WHERE … OR language.short_name IS NULL
一样简单。