2010-01-27 5 views
2

Mon problème est le suivant:MySQL charge SELECT

Mes tableaux sont MESSAGE et MESSAGE_COMMENT,

MESSAGE (id,content) 

MESSAGE_COMMENT (id, message_id, content) 

je dois sélectionner tous les messages et max 3 commentaires pour chaque message, comme dans cet exemple:

type | id | content 
M  15 "this is a message with no comments" 
M  16 "this is another message with many comments" 
R  16 "comment1" 
R  16 "comment2" 
R  16 "comment3" 
M  17 "this is another message with no comments" 

"id" est MESSAGE.id quand c'est un message et COMMENT.message_id quand c'est un commentaire.

J'espère avoir clairement expliqué mon problème ..

+0

Est-ce que les commentaires peuvent être dans n'importe quel ordre ou doivent-ils être triés par identifiant? –

+0

Avez-vous vraiment besoin de votre requête pour inclure des valeurs de différentes tables/colonnes dans le champ 'content' comme ceci? Si vous aviez des colonnes différentes dans vos données renvoyées pour le contenu des messages et le contenu des commentaires, vous seriez en mesure d'écrire une requête SQL plus simple. –

Répondre

1
SELECT * 
FROM (
     SELECT m.id, 
       COALESCE(
       (
       SELECT id 
       FROM message_comment mc 
       WHERE mc.message_id = m.id 
       ORDER BY 
         mc.message_id DESC, id DESC 
       LIMIT 2, 1 
       ), 0) AS mid 
     FROM message m 
     ) mo 
LEFT JOIN 
     message_comment mcd 
ON  mcd.message_id >= mo.id 
     AND mcd.message_id <= mo.id 
     AND mcd.id >= mid 

Créer un index sur message_comment (message_id, id) pour que cela fonctionne rapidement.

Voir cet article dans mon blog pour une explication plus détaillée de la façon dont cela fonctionne:

+0

merci pour votre réponse. J'ai essayé la requête mais elle n'affiche pas les messages sans commentaire. Comment puis-je résoudre ce problème? – AldoB

+0

@unknown (yahoo): remplace le 'JOIN' par un' LEFT JOIN'. J'ai mis à jour la requête. – Quassnoi

+0

..employer JOIN avec LEFT JOIN retourne toutes les valeurs à NULL ... – AldoB

0

C'est parce que PHP est analysé dans votre serveur (côté) et le code HTML généré par celui-ci aller au navigateur client et se renderized ...

+1

Semble être la mauvaise fenêtre :) – Quassnoi

0

Je ne suis pas fan des syndicats, mais parfois ils ont leur ... :)

SELECT type, id, content FROM ( 
SELECT 'M' AS type, id, 0 AS reply_id, content FROM MESSAGE 
UNION 
SELECT 'R' AS type, message_id AS id, id AS reply_id, content FROM MESSAGE_COMMENT) a 
ORDER BY id, reply_id 

retours

+------+----+--------------------------------------------+ 
| type | id | content         | 
+------+----+--------------------------------------------+ 
| M | 15 | this is a message with no comments   | 
| M | 16 | this is another message with many comments | 
| R | 16 | comment1         | 
| R | 16 | comment2         | 
| R | 16 | comment3         | 
| M | 17 | this is another message with no comments | 
+------+----+--------------------------------------------+ 

NB: Le deuxième SELECT dans le UNION pourraient facilement être retravaillés avec un INNER JOIN à la table MESSAGE si message_comments orphelins étaient une préoccupation.