2010-07-28 6 views
2

J'ai un problème avec mon instruction MySQL. J'ai besoin d'une requête qui compte le nombre de commentaires et le nombre de sujets qu'un utilisateur a créé. Ma structure de table est quelque chose comme ceci:MySQL JOIN avec 3 tables et COUNT() ne fonctionne pas

Table 'users' 
------------- 
user_id 
user_name 
... 

Table 'topics' 
-------------- 
topic_id 
topic_user_id 
... 

Table 'topiccomments' 
--------------------- 
topiccomment_id 
topiccomment_user_id 
... 

Jusqu'à présent, j'ai pu produire cette requête:

SELECT 
    u.user_id, 
    u.user_name, 
    COUNT(t.topic_user_id) as topic_count, 
    COUNT(tc.topiccomment_user_id) as topiccomment_count 
FROM 
    users as u 
    JOIN topiccomments as tc ON u.user_id = tc.topiccomment_user_id 
    JOIN topics as t ON u.user_id = t.topic_user_id 
WHERE 
    u.user_id = t.topic_user_id AND 
    u.user_id = tc.topiccomment_user_id 
GROUP BY 
    u.user_id 

Cette requête est exécutée, mais les valeurs « TOPIC_COUNT » et « topiccomment_count » sont totalement faux et je ne comprends pas pourquoi.

J'espérais que quelqu'un ici pourrait m'aider?

+0

Il est préférable de le faire en deux requêtes distinctes. Si vous avez vraiment besoin d'une requête, créez deux sous-requêtes. – mdma

+0

Je l'ai besoin dans une requête parce que je dois être capable de faire le tri mysql dans les champs 'topic_count' et 'topiccomment_count' ... A quoi ressemblerait la requête avec des sous-requêtes? Je n'ai aucune expérience avec des sous-requêtes ... – brtdv

+0

peut-être vous pouvez donner un exemple avec les données, les mauvais et les résultats prévus – Nicolas78

Répondre

5

changement

COUNT(DISTINCT t.topic_id) as topic_count, 
COUNT(DISTINCT tc.topiccomment_id) as topiccomment_count 

Cela comptera le nombre de sujets distincts et commentaires de sujets qui correspondent à l'ID utilisateur. Avant, vous comptiez le nombre de lignes dans le produit croisé des sujets et des commentaires de sujet pour un utilisateur donné. Si cela fonctionne dans votre situation, je refactoriserait cela en deux requêtes, une pour le comptage des sujets et une pour les commentaires sur les sujets, car cela sera plus efficace.

+0

Oui, c'est ça! La requête fonctionne maintenant! Merci beaucoup! gr, bert – brtdv

2

tir rapide: essayez de remplacer le nombre (champ) avec comptage (champ distinct)

+0

Salut, merci d'avoir répondu que rapide!Je l'ai essayé aussi, mais le 'topic_count' et le 'topiccomment_count' renvoient juste '1', alors que ce devrait être un nombre plus élevé ... – brtdv

2

Tout d'abord, vous pouvez supprimer toute votre clause WHERE. Ce n'est pas nécessaire parce que vous en avez déjà pris soin dans les JOINs.

Pour résoudre votre problème, utilisez dans votre clause SELECT au lieu des déclarations COUNT actuelles ont votre:

COUNT(DISTINCT t.topic_id) as topic_count, 
COUNT(DISTINCT tc.topiccomment_id) as topiccomment_count 

Vous essayez de compter le nombre de sujets ou des commentaires de sujet. Pas le nombre d'utilisateurs (qui devrait toujours être 1).

+0

Oui, c'est ça! La requête fonctionne maintenant! Merci beaucoup! gr, bert – brtdv

0

Vous devez compter les identifiants de sujet et de commentaire, pas les user_ids du commentaire/sujet.

SELECT 
    u.user_id, 
    u.user_name, 
    COUNT(DISTINCT t.topic_id) as topic_count, 
    COUNT(DISTINCT tc.topiccomment_id) as topiccomment_count 
FROM 
    users as u 
    JOIN topiccomments as tc ON u.user_id = tc.topiccomment_user_id 
    JOIN topics as t ON u.user_id = t.topic_user_id 
GROUP BY 
    u.user_id 
1

Le JOIN sont probablement retourner un produit cartésien des tables topiccomments et topics parce qu'il n'y a aucune restriction entre leur relation, ce qui pourrait expliquer pourquoi vous obtenez un nombre élevé.

Un moyen facile de résoudre ce problème est d'utiliser les sous-requêtes: corrélées

SELECT u.user_id, 
     u.user_name, 
     SELECT (COUNT(*) FROM topics t WHERE t.id = u.id), 
     SELECT (COUNT(*) FROM topiccomments tc WHERE tc.id = u.id) 
FROM users u; 

Vous pouvez également utiliser COUNT(DISTINCT t.topic_id) et COUNT(DISTINCT tc.topiccomment_id) dans votre requête d'origine comme certains des autres réponses suggèrent. En fait, cela peut s'avérer plus efficace en termes de performance.