首页 >数据库 >mysql教程 >当加入多个'GROUP_BY”时,如何避免'GROUP_CONCAT”中出现重复?

当加入多个'GROUP_BY”时,如何避免'GROUP_CONCAT”中出现重复?

Linda Hamilton
Linda Hamilton原创
2025-01-18 06:16:09310浏览

How to Avoid Duplicates in `GROUP_CONCAT` When Joining Multiple `GROUP_BY`s?

通过多个 GROUP_CONCAT 连接解决 GROUP BY 中的重复结果

通过 GROUP BY 组合多个 LEFT JOIN 子句并使用 GROUP_CONCAT 可能会导致重复的条目。这是由于合并每个 GROUP BY 中的唯一键而导致的,导致数据表示不准确。

问题场景

考虑这个查询结构:

<code class="language-sql">SELECT
    q1.user_id, q1.user_name, q1.score, q1.reputation, 
    SUBSTRING_INDEX(GROUP_CONCAT(q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2) AS top_two_tags,
    SUBSTRING_INDEX(GROUP_CONCAT(q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2) AS category
FROM
    (...) AS q1
    LEFT JOIN (...) AS q2 ON q2.user_id = q1.user_id 
    LEFT JOIN (...) AS q3 ON q3.user_id = q1.user_id 
GROUP BY
    q1.user_id, q1.user_name, q1.score, q1.reputation</code>

此查询旨在检索每个用户的前两个标签和类别,假设用户、标签、信誉、post_tag、类别和 post_category 表。 问题是由于加入了 GROUP BYs.

,可能会出现“css,css”或“technology,technology”等重复项。

有效的解决方案

有几种方法可以防止这些重复:

1。分离 GROUP BY 和内连接:

<code class="language-sql">-- Separate grouping and joining approach
SELECT
    q1.user_id, q1.user_name, q1.score, q1.reputation, q1.top_two_tags, q2.category
FROM
    (SELECT
        q1.user_id, q1.user_name, q1.score, q1.reputation, 
        SUBSTRING_INDEX(GROUP_CONCAT(q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2) AS top_two_tags
    FROM
        (...) AS q1
        LEFT JOIN (...) AS q2 ON q2.user_id = q1.user_id 
    GROUP BY
        q1.user_id, q1.user_name, q1.score, q1.reputation
    ) AS q1
    INNER JOIN
    (SELECT
        q1.user_id, 
        SUBSTRING_INDEX(GROUP_CONCAT(q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2) AS category
    FROM
        (...) AS q1
        LEFT JOIN (...) AS q3 ON q3.user_id = q1.user_id 
    GROUP BY
        q1.user_id
    ) AS q2
    ON q1.user_id = q2.user_id;</code>

此方法首先分别对标签和类别进行分组和连接,然后使用 INNER JOIN 上的 user_id 连接结果。 这可确保每个用户仅生成一行。

2。 标量子查询:

<code class="language-sql">-- Scalar subquery approach
SELECT
    q1.user_id, q1.user_name, q1.score, q1.reputation,
    (SELECT
        SUBSTRING_INDEX(GROUP_CONCAT(q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2)
    FROM (...) AS q2
    WHERE q2.user_id = q1.user_id
    ),
    (SELECT
        SUBSTRING_INDEX(GROUP_CONCAT(q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2)
    FROM (...) AS q3
    WHERE q3.user_id = q1.user_id
    )
FROM
    (...) AS q1;</code>

这使用 SELECT 列表中的子查询来单独获取每个用户的顶级标签和类别,避免 GROUP BY 歧义。

关键是在多个表上使用 GROUP_CONCAT 时,避免在单个 GROUP BY 调用中直接连接来自多个连接表的数据。 所选择的解决方案取决于具体的数据库结构和性能考虑。 目标是产生准确、无重复的结果。

以上是当加入多个'GROUP_BY”时,如何避免'GROUP_CONCAT”中出现重复?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn