2011-10-07 6 views
0

J'ai 3 tables différentes:SQL obtenir des données de plusieurs tables

Messages, Commentaires et Avatar. Ce que je voudrais faire est le suivant: Recevez tous les messages dans la base de données, en comptant pour chaque message les commentaires et en montrant l'avatar de chaque utilisateur.

Voici comment les tables sont construites:

Messages -> messages_id, user_id, titre, un message

Commentaires -> comments_id, messages_id, commentent

Avatar -> avatar_id, user_id, avatar

J'ai essayé les éléments suivants:

SELECT *, COUNT(comments.comments_id) AS commentCount 
FROM messages 
LEFT JOIN comments ON messages.messages_id = comments.messages_id 
LEFT JOIN avatar on messages.user_id = avatar.user_id 

Mais je reçois seulement une ligne pour les messages, le reste n'est pas visible.

Une idée de ce que je fais mal ici?

Répondre

1

Vous devez utiliser le GROUP BY:

SELECT messages_id 
     , title 
     , message 
     , user_id 
     , avatar_id 
     , avatar 
     , count(*) as commentCount 
    FROM messages 
    inner join avatar on messages.user_id = avatar.user_id 
    left join comments on messages.messages_id = comments.messages_id 
GROUP BY messages_id 

Cela devrait fonctionner si:

  • messages_id est unique dans messages
  • user_id est unique dans avatar

Sinon, vous besoin de spéci fy la valeur que vous voulez obtenir.

Modifié:

J'ai écrit inner join pour la table avatar pensant à ce que tous les utilisateurs ont un avatar. Si ce n'est pas vrai devrait être left join comme dans votre requête.

Deuxième essai

Peut-être que l'erreur était que le group by devrait être messages.messages_id au lieu de messages_id. En fait, dans d'autres SGBDR c'est une erreur:

ERROR: column reference "messages_id" is ambiguous

Je vais être plus précis:

SELECT m.messages_id as id 
     , min(m.title)  as title 
     , min(m.message) as message 
     , min(m.user_id) as user_id 
     , min(a.avatar_id) as avatar_id 
     , min(a.avatar) as avatar 
     , count(c.comments_id) as commentCount 
    FROM messages as m 
    left join avatar as a on m.user_id = a.user_id 
    left join comments as c on m.messages_id = c.messages_id 
GROUP BY m.messages_id 

Tous les min pourraient être supprimés dans MySQL si vous êtes sûr qu'il n'y a qu'une seule valeur . En SQL standard, vous devez choisir la valeur que vous voulez, s'il n'y en a qu'une, vous pouvez taper min ou max.

Je change de joint avec avatar pour être left join. Probablement pas tous les utilisateurs ont un avatar.

+0

Merci David pour votre réponse. Mais je reçois toujours un seul message au lieu des 2 messages que j'ai dans ma base de données. Messages_id est en effet unique dans les messages et user_id est unique dans avatar. Peut-être que je dois spécifier que tous les messages n'ont pas de commentaires. – moonwalker

+0

@moonwalker vérifie la deuxième requête que j'ai écrite. Si cela ne fonctionne pas, il serait utile d'avoir un exemple de données de table, de sortie attendue et de sortie réelle. – DavidEG

+0

Merci beaucoup David. Votre deuxième solution fonctionne très bien. Je vais l'étudier et essayer de comprendre ce que j'ai fait de mal. – moonwalker

Questions connexes