我有一个MySQL查询,每个帖子最多可以选择3条评论(如果有的话):
SELECT p.*, c.*
FROM posts p
LEFT JOIN comments c ON (p.post_id=c.post_id)
AND c.comment_id >
(SELECT comment_id FROM comments
WHERE post_id=p.post_id ORDER BY comment_id DESC LIMIT 3
)
我还想对这些帖子进行分页。例如,我想限制每页只有10个帖子。
仅供澄清 - 我的意思是10个DISTINCT帖子用于分页,而不是3个帖子在结果查询中,3个评论用于每个帖子。我的意思是这些帖子有10个不同的帖子*评论(每个帖子最多3个)。
如何在此查询中的帖子中引入分页?
另一个解决方案:
此外,我还为此任务找到了另一个解决方案:
SELECT *
FROM
(
SELECT *
FROM posts
LIMIT 0, 10
) p
LEFT JOIN
(
SELECT c.*,
@rownumber := CASE WHEN @post_id = post_id THEN @rownumber + 1 ELSE 1 END AS n,
@post_id := post_id
FROM comments c,
(SELECT @rownumber := 0, @post_id := 0) r
ORDER BY post_id DESC
) c ON p.post_id = c.post_id
WHERE c.post_id IS NULL OR n BETWEEN 1 and 3
答案 0 :(得分:3)
您在 SELECT
中使用的语法与您的评论相同:
LIMIT 0, 10
但是,您的查询有使用LIMIT 3, 1
(仅返回第四行)而不是LIMIT 0, 3
或LIMIT 3
的错误。
这不是一个容易编写的查询,因为它非常复杂,但我在下面编写了一个更简单的版本,可以满足您的需求。如果您想要选择30条评论,每篇文章最多3条评论,这会更容易,但这显然不是您想要做的。
基本上,查询会返回前10个posts
,每个评论都有2个字段(comments.id
和comments.comment
),这使得这三个评论共有6个字段。
如何通过使用带有评论表的三个LEFT JOIN
来实现这一点,每个评论表与之前的id
具有不同的LEFT JOIN
。这会为每个帖子创建最多三行,因此我们使用GROUP BY p.id
将它们全部合并为一行
该查询还使用ORDER BY p.id ASC
,因为使用LIMIT
而不使用ORDER BY
是不可预测的(数据库引擎在大多数情况下会在内部对结果应用ORDER BY
子句。)
注意:如果
INDEX
上有comments.post_id
,则此查询速度非常快。
SELECT p.*,
c1.id AS comment1_id, c1.comment AS comment1,
c2.id AS comment2_id, c2.comment AS comment2,
c3.id AS comment3_id, c3.comment AS comment3
FROM posts AS p
LEFT JOIN comments AS c1 ON c1.post_id = p.id
LEFT JOIN comments AS c2 ON c2.post_id = p.id AND c2.id <> c1.id
LEFT JOIN comments AS c3 ON c3.post_id = p.id AND c3.id <> c1.id AND c3.id <> c2.id
GROUP BY p.id
ORDER BY p.id ASC
LIMIT 0, 10;
| id | post | comment1_id | comment1 | comment2_id | comment2 | comment3_id | comment3 |
|----|------------|-------------|-----------|-------------|-----------|-------------|-----------|
| 1 | Post 1... | 1 | Comment 1 | 2 | Comment 2 | (null) | (null) |
| 2 | Post 2... | 3 | Comment 3 | 8 | Comment 8 | 9 | Comment 9 |
| 3 | Post 3... | (null) | (null) | (null) | (null) | (null) | (null) |
| 4 | Post 4... | 4 | Comment 4 | 5 | Comment 5 | 7 | Comment 7 |
| 5 | Post 5... | (null) | (null) | (null) | (null) | (null) | (null) |
| 6 | Post 6... | (null) | (null) | (null) | (null) | (null) | (null) |
| 7 | Post 7... | (null) | (null) | (null) | (null) | (null) | (null) |
| 8 | Post 8... | (null) | (null) | (null) | (null) | (null) | (null) |
| 9 | Post 9... | (null) | (null) | (null) | (null) | (null) | (null) |
| 10 | Post 10... | 6 | Comment 6 | (null) | (null) | (null) | (null) |
有关在线示例,请参阅http://sqlfiddle.com/#!9/182db/4。
通过检查null
的字段,您可以检查该帖子是否有评论,以及发布的评论数量。
注意:您应该坚持使用大写作为SQL关键字,因为这是行业最佳惯例。