2012-10-23 55 views
3

我有一個查詢以這種降序返回結果。獲取結果集中每個id的`n`行MYSQL

comment  postid  name  userid tempid 
    ----------------------------------------------------- 
    c1   199  User1  123321 1 
    c2   199  User1  123321 2 
    c3   199  User1  123321 3 
    c4   199  User1  123321 4 
    c5   199  User1  123321 5 
    c6   199  User1  123321 6 
    c7   198  User1  123321 7 
    c8   198  User1  123321 8 
    c9   198  User1  123321 9 
    c10   197  User1  123321 10 
    c11   197  User1  123321 11 
    c12   197  User1  123321 12 
    c13   197  User1  123321 13 
    c14   197  User1  123321 13 
    c15   197  User1  123321 13 
    c16   197  User1  123321 13 

現在我想選擇前5個記錄每個postid .The dersired結果應該是

comment  postid  name  userid tempid 
    ----------------------------------------------------- 
    c1   199  User1  123321 1 
    c2   199  User1  123321 2 
    c3   199  User1  123321 3 
    c4   199  User1  123321 4 
    c5   199  User1  123321 5 
    c7   198  User1  123321 7 
    c8   198  User1  123321 8 
    c9   198  User1  123321 9 
    c10   197  User1  123321 10 
    c11   197  User1  123321 11 
    c12   197  User1  123321 12 
    c13   197  User1  123321 13 
    c14   197  User1  123321 13 

這裏是我的查詢。

DECLARE rangee INT; 
DECLARE uid BIGINT; 

SET @rangee = plimitRange * 10; 
SET @uid = puserid; 

PREPARE STMT FROM 
' 
SELECT comments.comment,comments.postid,user.name,comments.userid,comments.tempid 
FROM 
user 
INNER JOIN comments ON user.userid=comments.userid 
INNER JOIN posts ON posts.postID = comments.postid 
WHERE 
comments.postid <= 
(SELECT MAX(postid) FROM 
(
    SELECT wall.postid FROM wall,posts WHERE 
    wall.postid = posts.postid AND posts.userid=? 
    ORDER BY wall.postid DESC LIMIT 10 OFFSET ? 
)sq1 
) 

AND 
comments.postid >= 
(SELECT MIN(postid) FROM 
(
    SELECT wall.postid FROM wall,posts WHERE 
    wall.postid = posts.postid AND posts.userid=? 
    ORDER BY wall.postid DESC LIMIT 10 OFFSET ? 
)sq2 
) 

AND 
posts.userid = ? 
ORDER BY comments.postid DESC,comments.tempid DESC; 
'; 
EXECUTE STMT USING @uid,@rangee,@uid,@rangee,@uid; 
DEALLOCATE PREPARE STMT; 

我該如何做到這一點?

+0

我會想象得到的意見表從子查詢,上面有一個極限,而不是直接加入會起作用。可能相關:http://stackoverflow.com/q/2856397/438971 – Orbling

+0

thnx的答覆,但你可以幫助我在查詢中指定它? – Mj1992

+0

你看過評論中的答案鏈接嗎?在MySQL中的高級採樣,這有點令人困惑:http://explainextended.com/2009/03/06/advanced-row-sampling/ – Orbling

回答

3

您必須使用子查詢來實現每個記錄(評論)中包含每個組內的排名(通過發佈)的表。然後,在外部查詢,您可以篩選出只所需的範圍(例如[1,5]頂級5)內的一個等級記載:

-- select top 5 comments of each of the user's desired posts 
SELECT comments.comment, 
     comments.postid, 
     user.name, 
     comments.userid, 
     comments.tempid 
FROM  user JOIN (
      -- rank comments on user's desired posts by grouping a self-join 
      -- use index (postid, tempid) for performance 
      SELECT  c1.*, COUNT(*) rank 
      FROM  (
         -- select user's posts within desired range 
         SELECT postid 
         FROM (
            -- rank user's posts by grouping a self-join 
            -- use index (userid, postid) for performance 
            SELECT  p1.postid, COUNT(*) rank 
            FROM  posts p1 
            LEFT JOIN posts p2 
              ON p1.userid = p2.userid 
              AND p1.postid < p2.postid 
            WHERE  p1.userid = @uid 
            GROUP BY p1.postid 
           ) ranked_posts 
         WHERE rank BETWEEN @rangee + 1 AND @rangee + 10 
         ) interesting_posts 
        JOIN comments c1 USING (postid) 
      LEFT JOIN comments c2 
        ON c1.postid = c2.postid 
        AND c1.tempid < c2.tempid 
      GROUP BY c1.postid 
     ) comments USING (userid) 
WHERE comments.rank BETWEEN 1 AND 5 
ORDER BY postid DESC, tempid DESC 
+0

'用戶期望的帖子的評論等級?你能解釋一下這是什麼意思嗎?什麼'c1。*,IFNULL(COUNT(*),0)等級這部分是做什麼'rank' ???????? – Mj1992

+0

您想要選擇前N個評論,所以我們需要對每篇文章的評論進行排名,然後將結果限制爲僅限於排名區間'[1,5]'中的評論。在該部分中,「rank」是前面表達式的結果的別名(列名)。 – eggyal

+0

當我運行你的查詢時說'列的列不能爲空',你能解釋一下'IFNULL(COUNT(*),0)'這個意思嗎? – Mj1992