我正在使用 MySQL 8 和 PHP 实现一个经典的“三表标签系统”:
我编写的用于显示前 10 篇帖子的查询是:
SELECT p.PostTitle, p.PostSummary, ...,
JSON_OBJECTAGG(t.TagSlug, t.TagName)
FROM (SELECT ... FROM Posts WHERE ... ORDER BY ... DESC LIMIT 10) p
LEFT JOIN TagsMap tm ON p.PostId = tm.TagId
LEFT JOIN Tags t ON tm.TagName = t.TagId
GROUP BY p.PostId
ORDER BY p.PostId DESC
它有效。
当帖子没有关联标签时,就会出现问题。在这种情况下,我收到以下错误:
"PDOException: SQLSTATE[22032]: <>: 3158 JSON documents may not contain NULL member names".
换句话说,JSON_OBJECTAGG 的键(t.TagSlug)不能为空。
我该如何修复它?
我假设您想要所有帖子的结果,无论它们是否有标签。所以你不能只使用
WHERE t.tagSlug IS NOT NULL
,因为这会遗漏没有标签的帖子。
运行两项查询,一项针对至少具有一个标签的帖子,一项针对没有标签的帖子。可以选择合并结果。
(SELECT p.PostTitle, p.PostSummary, ...,
JSON_OBJECTAGG(t.TagSlug, t.TagName) AS TagsObject
FROM (SELECT ... FROM Posts WHERE ... ORDER BY ... DESC LIMIT 10) p
INNER JOIN TagsMap tm ON p.PostId = tm.TagId
INNER JOIN Tags t ON tm.TagName = t.TagId
GROUP BY p.PostId)
UNION
(SELECT p.PostTitle, p.PostSummary, ...,
NULL
FROM (SELECT ... FROM Posts WHERE ... ORDER BY ... DESC LIMIT 10) p
LEFT OUTER JOIN TagsMap tm ON p.PostId = tm.TagId
WHERE tm.TagId IS NULL
GROUP BY p.PostId)
ORDER BY PostId DESC;