Query, select pinned topics first, then all other topics
My current query is...
SELECT * FROM (
SELECT * FROM (
SELECT
topic.id, topic.title, topic.description, topic.member_id, topic.member_name, topic.views, topic.post_count, topic.last_post_time, topic.last_post_author, topic.last_post_author_id
FROM topic
INNE开发者_如何学编程R JOIN topic_status_assoc
ON topic_status_assoc.topic_id = topic.id
INNER JOIN topic_status
ON topic_status.id = topic_status_assoc.status_id
WHERE topic_status.id = 2
AND topic.board_id = ".$this->_getId()."
AND EXISTS (
SELECT
id
FROM post
WHERE trash = 0
AND topic_id = topic.id
)
ORDER BY last_post_time DESC
) tab2
UNION ALL
SELECT * FROM (
SELECT
topic.id, topic.title, topic.description, topic.member_id, topic.member_name, topic.views, topic.post_count, topic.last_post_time, topic.last_post_author, topic.last_post_author_id
FROM topic
WHERE board_id = ".$this->_getId()."
AND id NOT IN (
SELECT
topic.id
FROM topic
INNER JOIN topic_status_assoc
ON topic_status_assoc.topic_id = topic.id
INNER JOIN topic_status
ON topic_status.id = topic_status_assoc.status_id
WHERE topic_status.id = 2
AND topic.board_id = ".$this->_getId()."
AND EXISTS (
SELECT
id
FROM post
WHERE trash = 0
AND topic_id = topic.id
)
)
AND EXISTS (
SELECT
id
FROM post
WHERE trash = 0
AND topic_id = topic.id
)
ORDER BY last_post_time DESC
) tab3
WHERE post_count > 0
) tab1
LIMIT ".$start.", ".$count
I'm sure you'd agree with me that this just doesn't look as efficient as it could be. Any ideas on how I could do this differently, some way of crazy optimizing this query ^_^
MySQL is the only database I'm aware of that allows brackets in UNION statements to allow for independent ORDER BY (and by extension, LIMIT) clauses:
(SELECT t.id,
t.title,
t.description,
t.member_id,
t.member_name,
t.views,
t.post_count,
t.last_post_time,
t.last_post_author,
t.last_post_author_id
FROM TOPIC t
JOIN topic_status_assoc tsa ON tsa.topic_id = t.id
JOIN topic_status ts ON ts.id = tsa.status_id
AND ts.id = 2
WHERE t.board_id = ".$this->_getId()."
AND t.post_count > 0
AND EXISTS (SELECT NULL
FROM POST p
WHERE p.trash = 0
AND p.topic_id = t.id)
ORDER BY t.last_post_time DESC)
UNION ALL
(SELECT t.id,
t.title,
t.description,
t.member_id,
t.member_name,
t.views,
t.post_count,
t.last_post_time,
t.last_post_author,
t.last_post_author_id
FROM TOPIC t
WHERE t.board_id = ".$this->_getId()."
AND t.post_count > 0
AND NOT EXISTS (SELECT NULL
FROM TOPIC
JOIN topic_status_assoc ON topic_status_assoc.topic_id = topic.id
JOIN topic_status ON topic_status.id = topic_status_assoc.status_id
AND topic_status.id = 2
WHERE topic.board_id = ".$this->_getId()."
AND EXISTS (SELECT NULL
FROM POST p
WHERE p.trash = 0
AND p.topic_id = topic.id))
AND EXISTS (SELECT NULL
FROM POST p
WHERE p.trash = 0
AND p.topic_id = t.id)
ORDER BY last_post_time DESC)
LIMIT ".$start.", ".$count
Please take the time to learn about using table aliases.
精彩评论