Maison >base de données >tutoriel mysql >Comment éviter les doublons dans `GROUP_CONCAT` lors de la jonction de plusieurs `GROUP_BY` ?

Comment éviter les doublons dans `GROUP_CONCAT` lors de la jonction de plusieurs `GROUP_BY` ?

Linda Hamilton
Linda Hamiltonoriginal
2025-01-18 06:16:09312parcourir

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

Résolution des résultats en double dans GROUP_CONCAT avec plusieurs GROUP BY jointures

Combiner plusieurs clauses GROUP BY via des LEFT JOIN et utiliser GROUP_CONCAT peut conduire à des entrées en double. Cela résulte de la fusion de clés uniques de chaque GROUP BY, ce qui entraîne une représentation inexacte des données.

Scénario de problème

Considérez cette structure de requête :

<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>

Cette requête vise à récupérer les deux principales balises et catégories pour chaque utilisateur, en supposant des tableaux pour les utilisateurs, les balises, les réputations, post_tag, les catégories et post_category. Le problème est le potentiel de doublons comme "css, css" ou "technology, technology" en raison des GROUP BY joints.

Solutions efficaces

Plusieurs méthodes peuvent éviter ces doublons :

1. Séparez GROUP BY et INNER JOIN :

<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>

Cette méthode regroupe et concatène d'abord les balises et les catégories séparément, puis joint les résultats à l'aide d'un INNER JOIN sur user_id. Cela garantit qu’une seule ligne par utilisateur est produite.

2. Sous-requêtes scalaires :

<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>

Cela utilise des sous-requêtes dans la liste SELECT pour récupérer les principales balises et catégories pour chaque utilisateur individuellement, évitant ainsi l'ambiguïté GROUP BY.

La clé est d'éviter de concaténer directement les données de plusieurs tables jointes au sein d'un seul appel GROUP_CONCAT lors de l'utilisation de GROUP BY sur plusieurs tables. La solution choisie dépend de la structure spécifique de la base de données et des considérations de performances. L'objectif est de produire des résultats précis et sans doublon.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn