为结果集中的每个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
现在我想为每个postid选择前5条记录.
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;
我该怎么做?
解决方法:
您必须使用子查询来实现一个表,该表包含每个记录(注释)在每个组(按帖子)内的排名.然后,在外部查询中,您只能过滤排名在所需范围内的记录(例如,前5位的[1,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
标签:greatest-n-per-group,mysql 来源: https://codeday.me/bug/20191127/2074381.html