2011-05-21 5 views
1

J'utilise requête MySQL imbriqué pour obtenir les messages de l'utilisateur, et quand je mets SQL_CALC_FOUND_ROWS dans la requête de l'enfant, l'erreur de retour MySQL: Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'SQL_CALC_FOUND_ROWS retour erreur

La requête est:

SELECT inner_table.* 
    , users.username as last_username 
    , posts.date_added as last_date_added 
    , users.user_id as last_user_id 
    , posts.date_added as last_post_date 
FROM (
    SELECT SQL_CALC_FOUND_ROWS topics.topic_id 
     , topics.date_added 
     , topics.title 
     , topics.user_id 
     , MAX(posts.post_id) as last_post 
     , posts.user_id as post_user_id 
     , users.username 
     , topics.previews 
     , topics.fcat_id 
     , topics.is_important 
     , topics.is_locked 
     , topics.lastpost_time 
     , (SELECT COUNT(*) FROM posts WHERE posts.topic_id=topics.topic_id) as posts_cnt 
    FROM topics 
    LEFT JOIN users ON (users.user_id = topics.user_id) 
    LEFT JOIN posts ON (topics.topic_id = posts.topic_id) 
    WHERE topics.user_id = ".$this->session->getSession("user_data", "user_id")." 
    OR ".$this->session->getSession("user_data", "user_id")." 
    IN (
     SELECT DISTINCT user_id 
     FROM posts 
     WHERE posts.topic_id = topics.topic_id 
    ) 
    GROUP BY topics.topic_id 
    ORDER BY topics.lastpost_time DESC 
    LIMIT ".$limit * $page.", ".$limit." 
    ) as inner_table 
LEFT JOIN `posts` ON (posts.post_id=inner_table.last_post) 
LEFT JOIN `users` ON (users.user_id=posts.user_id) 
ORDER BY inner_table.lastpost_time DESC 

Répondre

1

Je ne pense pas SQL_CALC_FOUND_ROWS est autorisé sur une requête interne.
Insérez la requête externe à la place.

SELECT SQL_CALC_FOUND_ROWS inner_table.* 
    .... 

vous avez également une erreur dans la dernière ligne:

ORDER BY inner_table.lastpost_time DES 

Remplacez-le par:

ORDER BY inner_table.lastpost_time DESC 

MISE À JOUR

En réponse à votre commentaire sur le travail suivant Idées autour de

Sort le sélecteur interne dans une table temporaire.

En utilisant du code comme ceci:

/* do this once*/ 
CREATE TABLE `temp_table` LIKE SELECT topics.topic_id 
     , topics.date_added .... 

/*do this for every query*/ 
DELETE FROM temp_table WHERE temp_table.topic_id <> 0; 
INSERT INTO temp_table SELECT topics.topic_id 
    , topics.date_added 
    , topics.title 
.... /*!! without the limit clause !!*/ 
SELECT count(*) as rowcount FROM temp_table; 

/*then use the temp_table in place of the inner select*/ 

SELECT inner_table.* 
, users.username as last_username 
    , posts.date_added as last_date_added 
    , users.user_id as last_user_id 
    , posts.date_added as last_post_date 
FROM temp_table ..... 
LIMIT .... 

En utilisant SQL_CALC_FOUND_ROWS ne fonctionne pas sur un INSERT .. SELECT non plus, mais le code ci-dessus est une solution de contournement, vous pouvez bien sûr exécuter la requête intérieure séparée avec un LIMIT 1 dessus pour le rendre aussi vite que possible.

+0

Non, cela n'a tout simplement pas été copié. L'erreur est une autre - Utilisation incorrecte/placement de 'SQL_CALC_FOUND_ROWS' –

+0

J'ai essayé de mettre SQL_CALC_FOUND_ROWS sur la requête externe, mais puis me renvoie seulement le nombre de LIMIT dans les résultats de la requête interne. –