对 LEFT JOIN 和 GROUP_CONCAT 中的重复数据进行故障排除
您的查询使用 LEFT JOINs
、GROUP BY
和 GROUP_CONCAT
收集每个用户的热门标签和类别,意外地产生了重复条目。
了解重复问题
问题源于多个LEFT JOINs
在用户、标签和类别之间创建多对多关系。 这会导致每个用户生成多行,每行代表不同的标签类别组合。 然后,GROUP BY
聚合这些内容,从而产生 GROUP_CONCAT
中的重复项。
解决方案:使用 DISTINCT 和 GROUP_CONCAT
要消除重复项,请在 DISTINCT
函数中添加 GROUP_CONCAT
关键字。这可确保仅连接唯一的标签和类别:
<code class="language-sql">SELECT q1.user_id, q1.user_name, q1.score, q1.reputation, SUBSTRING_INDEX(GROUP_CONCAT(DISTINCT q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2) AS top_two_tags, SUBSTRING_INDEX(GROUP_CONCAT(DISTINCT q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2) AS category FROM ...</code>
替代方案:用于清洁聚合的子查询
另一种策略完全避免 LEFT JOIN
和 GROUP BY
组合。 使用子查询(或用于更复杂场景的 CTE)提供了更受控制的聚合:
<code class="language-sql">SELECT u.user_id, u.user_name, u.score, u.reputation, (SELECT GROUP_CONCAT(tag ORDER BY tag_reputation DESC SEPARATOR ',') FROM post_tag WHERE user_id = u.user_id LIMIT 2) AS top_two_tags, (SELECT GROUP_CONCAT(category ORDER BY category_reputation DESC SEPARATOR ',') FROM post_category WHERE category_id = u.category_id LIMIT 2) AS category FROM users u</code>
此方法确保每个用户独立进行聚合,从而防止早期重复。 选择最适合您的数据库结构和查询复杂性的方法。
以上是为什么我的 LEFT JOIN 和 GROUP_CONCAT 会产生重复的结果?的详细内容。更多信息请关注PHP中文网其他相关文章!