2012-10-23 53 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