我有这个 SQL 查询来获取列表中每个 ID 的相关注释:
SELECT comments.id, comments.body, comments.created_at
, comments.like_count, comments.post_id
FROM comments
WHERE comments.is_active AND comments.is_show
AND comments.post_id in (1, 7, 9, 11, 3)
GROUP BY comments.id
ORDER BY comments.id
LIMIT 3 <----- this is not working correctly!
我想获取给定列表中每个帖子 ID 的前 3 条评论(1、7、9、11、3)。
如何实现这一目标?
最佳答案
这将削弱迄今为止建议的解决方案的性能:
SELECT c.*
FROM unnest('{1, 7, 9, 11, 3}'::int[]) AS p(post_id) -- assuming integer?
CROSS JOIN LATERAL (
SELECT id, body, created_at, like_count, post_id
FROM comments c
WHERE is_active
AND is_show
AND c.post_id = p.post_id
ORDER BY like_count DESC NULLS LAST -- assuming this defines "top"?
LIMIT 3
) c
ORDER BY id, like_count DESC NULLS LAST; -- see below
需要在(post_id, like_count)
上建立索引才能快速。
与使用 row_number()
的缓慢解决方案(必须扫描整个评论表)不同,这可以轻松地从索引中识别每个 post_id
的前 3 条评论。对于大表,速度要快几个数量级。
参见:
- Limit number of rows per group from join (NOT to 1 row)
- Optimize GROUP BY query to retrieve latest row per user
如果 like_count
定义为 NOT NULL
(可能应该如此),您可以简化为 ORDER BY id, like_count DESC
。否则,您需要DESC NULLS LAST
,并且最佳索引位于(post_id, like_count DESC NULLS LAST)
。关于这一点:
关于sql - 获取列表中每个 ID 的前 3 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73255603/