如何使用 SQL 查询获取文章及其前 5 条评论?

如何使用 SQL 查询获取文章及其前 5 条评论?
最新回答
盖世傻白甜

2024-02-04 03:14:54

要使用SQL查询获取文章及其前5条评论,可以采用以下方法。由于传统的LEFT JOIN无法直接限制每个文章的评论数量,我们需要使用子查询或窗口函数来实现这一需求。以下是几种实现方式:

方法1:使用子查询(适用于不支持窗口函数的旧版数据库)SELECT a.id AS article_id, a.content AS article_content, c.comment_id, c.comment_textFROM article aLEFT JOIN ( SELECT c1.pid, c1.id AS comment_id, c1.comment AS comment_text FROM comment c1 WHERE (SELECT COUNT(*) FROM comment c2 WHERE c2.pid = c1.pid AND c2.id >= c1.id) <= 5 ORDER BY c1.pid, c1.id) c ON a.id = c.pidORDER BY a.id, c.comment_id;说明
  1. 子查询逻辑:通过相关子查询筛选每个文章(pid)的前5条评论(按id升序或降序排列)。
  2. LEFT JOIN:将文章表与子查询结果关联,确保即使文章没有评论也会返回文章数据。
  3. 排序:最终结果按文章ID和评论ID排序。
方法2:使用窗口函数(推荐,适用于现代数据库如MySQL 8.0+、PostgreSQL、SQL Server)WITH ranked_comments AS ( SELECT c.id AS comment_id, c.pid AS article_id, c.comment AS comment_text, ROW_NUMBER() OVER (PARTITION BY c.pid ORDER BY c.id) AS row_num FROM comment c)SELECT a.id AS article_id, a.content AS article_content, rc.comment_id, rc.comment_textFROM article aLEFT JOIN ranked_comments rc ON a.id = rc.article_id AND rc.row_num <= 5ORDER BY a.id, rc.comment_id;说明
  1. 窗口函数:ROW_NUMBER()为每个文章的评论分配序号(按id排序)。
  2. 过滤评论:通过rc.row_num <= 5限制每个文章最多返回5条评论。
  3. 性能优化:窗口函数通常比子查询更高效,尤其在大数据量时。
方法3:使用JSON聚合(适用于需要返回嵌套结构的场景)

如果希望结果直接以JSON格式返回每篇文章及其评论列表(如输出示例),可使用以下方法(以MySQL 8.0+为例):

SELECT a.id, a.content, ( SELECT JSON_ARRAYAGG( JSON_OBJECT('commentid', c.id, 'comment', c.comment) ) FROM ( SELECT id, comment FROM comment WHERE pid = a.id ORDER BY id LIMIT 5 ) c ) AS commentListFROM article a;说明
  1. 子查询+LIMIT:直接限制每个文章的评论数量。
  2. JSON聚合:将评论列表转换为JSON数组,便于应用层处理。
注意事项
  1. 数据库兼容性:窗口函数需MySQL 8.0+、PostgreSQL等支持;旧版数据库需用方法1。
  2. 性能:对大表建议添加索引(如comment.pid和comment.id)。
  3. 排序逻辑:根据需求调整ORDER BY(如按时间降序取最新5条评论)。
输出示例(方法3的结果)[ { "id": 1, "content": "文章内容 1", "commentList": [ {"commentid": 1, "comment": "评论 1"}, {"commentid": 2, "comment": "评论 2"}, {"commentid": 3, "comment": "评论 3"}, {"commentid": 4, "comment": "评论 4"}, {"commentid": 5, "comment": "评论 5"} ] }, { "id": 2, "content": "文章内容 2", "commentList": [ {"commentid": 6, "comment": "评论 6"}, {"commentid": 7, "comment": "评论 7"} ] }]

根据实际需求选择合适的方法,窗口函数通常是首选方案。