This query returns forum questions/answers and their nested comments (similar to the StackOverflow paradigm).
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
I am trying to paginate the results and am hitting the following problem:
By placing LIMIT at the end of the query, I end up limiting the number of total rows, not the number of questions/answers.
For ex, LIMIT 0,3 in the last line gives me (qa: question/answer; cm: comment):
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
instead of
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
Any suggestions how to modify my query in order to have LIMIT 0,3 return not 3 rows but 3 questions regardless of how many nested comments is has?
changes with @michael’s suggestion
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
(HOPEFULLY) THE SOLUTION
After reading here
http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/
I decided to index the field I wanted to ORDER BY (forum_qa_type) — once I did this, the query is returning the correct number of questions.
Thanks @Michael for helping out. Will update here if this stops working.
Assuming
forum_qais the table holding the questions, you can place itsSELECT *into a subquery with its own limit. This is of course untested, but should work in principle.Additional references to the table name
forum_qawill need to be changed to its new aliasqa.