开发者

Query, select pinned topics first, then all other topics

开发者 https://www.devze.com 2023-01-24 10:30 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号