2011-10-16 4 views
2

Cette requête renvoie les questions/réponses du forum et leurs commentaires imbriqués (similaire au paradigme StackOverflow).Besoin d'aide pour placer LIMIT, OFFSET dans cette requête MySQL

SELECT forum_qa.*, 
      user_profiles.*, 
      c.*, 
      n.pid, 
      v.*, 
      Ifnull(n.ans_count, 0) AS ans_count 
    FROM forum_qa 
      JOIN user_profiles 
      ON user_id = forum_qa_author_id 
      LEFT JOIN (SELECT * 
         FROM votes) AS v 
      ON forum_qa_id = v.forum_qa_id_fk 
      LEFT JOIN (SELECT forum_cm_id, 
          forum_cm_author_id, 
          forum_qa_id_fk, 
          forum_cm_text, 
          forum_cm_timestamp, 
          forum_cm_flag, 
          first_name AS forum_cm_first_name, 
          last_name AS forum_cm_last_name, 
          facebook_id AS forum_cm_fb_id, 
          picture  AS forum_cm_picture, 
          moderator AS forum_cm_moderator 
         FROM forum_cm 
          JOIN user_profiles 
           ON user_id = forum_cm_author_id) AS c 
      ON forum_qa_id = c.forum_qa_id_fk 
      LEFT JOIN (SELECT forum_qa_parent_id AS pid, 
          COUNT(*)   AS ans_count 
         FROM forum_qa 
         WHERE forum_qa_parent_id IS NOT NULL 
         GROUP BY forum_qa_parent_id) AS n 
      ON forum_qa_id = n.pid 
    WHERE forum_qa_id LIKE "%" 
      AND forum_qa_parent_id IS NULL 
    ORDER BY forum_qa_timestamp DESC 
      LIMIT 0,3 

Je suis en train de paginer les résultats et je frappais le problème suivant:

En plaçant LIMIT à la fin de la requête, je finissent par limiter le nombre de au total lignes, non le nombre de questions/réponses.

Ex, LIMIT 0,3 dans la dernière ligne me donne (qa: questions/réponses; cm: un commentaire):

forum_qa_id qa_text forum_cm_id cm_text 
1    asd 
2    wer  4    this is a comment 
2    wer  5    this is another comment 

au lieu de

forum_qa_id qa_text forum_cm_id cm_text 
1    asd 
2    wer  4    this is a comment 
2    wer  5    this is another comment 
3    zxc  
3    zxc  7    yet another comment 

Toute suggestion comment modifier ma requête dans ordre d'avoir LIMIT 0,3 retourner pas 3 lignes mais 3 questions quel que soit le nombre de commentaires imbriqués est a?

changements avec @ la suggestion de Michael

SELECT qa.*, 
      user_profiles.*, 
      c.*, 
      n.pid, 
      v.*, 
      Ifnull(n.ans_count, 0) AS ans_count 
    FROM (SELECT * FROM forum_qa LIMIT 0, 3) qa 
      JOIN user_profiles 
      ON user_id = qa.forum_qa_author_id 
      LEFT JOIN (SELECT * 
         FROM votes) AS v 
      ON qa.forum_qa_id = v.forum_qa_id_fk 
      LEFT JOIN (SELECT forum_cm_id, 
          forum_cm_author_id, 
          forum_qa_id_fk, 
          forum_cm_text, 
          forum_cm_timestamp, 
          forum_cm_flag, 
          first_name AS forum_cm_first_name, 
          last_name AS forum_cm_last_name, 
          facebook_id AS forum_cm_fb_id, 
          picture  AS forum_cm_picture, 
          moderator AS forum_cm_moderator 
         FROM forum_cm 
          JOIN user_profiles 
           ON user_id = forum_cm_author_id) AS c 
      ON qa.forum_qa_id = c.forum_qa_id_fk 
      LEFT JOIN (SELECT forum_qa_parent_id AS pid, 
          COUNT(*)   AS ans_count 
         FROM forum_qa 
         WHERE forum_qa_parent_id IS NOT NULL 
         GROUP BY forum_qa_parent_id) AS n 
      ON qa.forum_qa_id = n.pid 
    WHERE qa.forum_qa_id LIKE "%" 
      AND qa.forum_qa_parent_id IS NULL 
    ORDER BY qa.forum_qa_timestamp DESC 

(VA BIEN) LA SOLUTION

Après avoir lu ici

http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/

j'ai décidé d'indexer le champ que je voulais ORDER BY (forum_qa_type) - une fois que j'ai fait cela, la requête retourne le nombre correct de questions.

Merci à Michael d'avoir aidé. Mettra à jour ici si cela cesse de fonctionner.

+0

Vous venez de remarquer que vous avez modifié ceci. Combien de lignes obtenez-vous avec seulement la jointure unique contre 'user_profiles'? –

+0

hey michael jeter un oeil à la nouvelle info que j'ai mis sous "version courte". C'est ahurissant. – pepe

+1

mettre un 'ORDER BY 'explicite dans la sous-requête' qa': 'ORDER BY quelque chose LIMIT 0,3' –

Répondre

5

En supposant que forum_qa est la table contenant les questions, vous pouvez placer son SELECT * dans une sous-requête avec sa propre limite. Ceci est bien sûr non testé, mais devrait fonctionner en principe.

SELECT  qa.*, 
      user_profiles.*, 
      c.*, 
      n.pid, 
      v.*, 
      Ifnull(n.ans_count, 0) AS ans_count 
    FROM (SELECT * FROM forum_qa LIMIT 0, 3) qa 
      JOIN user_profiles 
      ON user_profiles.user_id = qa.forum_qa_author_id 
      LEFT JOIN (SELECT *..... 
      -- etc... 

références supplémentaires au nom de la table forum_qa devront être changé à son nouvel alias qa.

+0

merci pour le conseil, mais je pense que je suis foireux quelque part - j'ai posté le code mis à jour dans OP - il renvoie encore 3 lignes au lieu de 3 questions - aucune idée de ce que je fais mal? – pepe

+0

@torr Je ne vois pas d'autres problèmes - vous avez 'LEFT JOIN's le cas échéant.Je suggère de supprimer d'autres tables/sous-requêtes jointes et de les ajouter progressivement au débogage –

+0

vient de poster ce que * semble * pour résoudre le problème - thx – pepe

Questions connexes