【问题标题】:SQL Query Question: X has many Y. Get all X and get only the newest Y per XSQL 查询问题:X 有很多 Y。获取所有 X 并仅获取每个 X 中最新的 Y
【发布时间】:2009-04-29 21:41:21
【问题描述】:

假设我们有两张桌子。发布和评论。帖子有很多评论。假装他们有些人满,因此每个帖子的 cmets 数量是不同的。我想要一个查询,它会抓取所有帖子,但只抓取每条帖子的最新评论。

我已被引导到连接和子查询,但我无法弄清楚。

示例输出:

帖子1: 评论 4(post1 的最新消息)

帖子2: 评论 2(post2 的最新)

帖子 3: 评论 10(post3 的最新消息)

等等……

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: sql mysql database join


    【解决方案1】:

    此答案假定您对每条评论都有一个唯一标识符,并且该标识符的数量不断增加。也就是说,后面的帖子比以前的帖子有更多的数字。不必是顺序的,只要与输入的顺序相对应即可。

    首先,执行一个查询,提取最大评论 ID,按帖子 ID 分组。

    类似这样的:

    SELECT MAX(ID) MaxCommentID, PostID
    FROM Comments
    GROUP BY PostID
    

    这将为您提供一个帖子 ID 列表,以及每个帖子的最高(最新)评论 ID。

    然后你加入这个,从 cmets 中提取其余数据,用于那些 id。

    SELECT C1.*, C2.PostID
    FROM Comments AS C1
         INNER JOIN (
             SELECT MAX(ID) MaxCommentID, PostID
             FROM Comments
             GROUP BY PostID
         ) AS C2 ON C1.CommentID = C2.MaxCommentID
    

    然后,您加入帖子,以获取有关这些帖子的信息。

    SELECT C1.*, P.*
    FROM Comments AS C1
         INNER JOIN (
             SELECT MAX(ID) MaxCommentID, PostID
             FROM Comments
             GROUP BY PostID
         ) AS C2 ON C1.CommentID = C2.MaxCommentID
         INNER JOIN Posts AS P ON C2.PostID = P.ID
    

    另一种方法根本不使用内部查询的 PostID。首先,选择所有唯一帖子的最大评论 ID,但不要关心哪个帖子,我们知道它们是唯一的。

    SELECT MAX(ID) AS MaxCommentID
    FROM Comments
    GROUP BY PostID
    

    然后执行一个 IN 子句,以获取这些 cmets 的其余数据:

    SELECT C1.*
    FROM Comments
    WHERE C1.ID IN (
        SELECT MAX(ID) AS MaxCommentID
        FROM Comments
        GROUP BY PostID
    )
    

    然后只需加入帖子:

    SELECT C1.*, P.*
    FROM Comments AS C1
         INNER JOIN Posts AS P ON C1.PostID = P.ID
    WHERE C1.ID IN (
        SELECT MAX(ID) AS MaxCommentID
        FROM Comments
        GROUP BY PostID
    )
    

    【讨论】:

      【解决方案2】:

      从子查询中选择最新的评论

      例如

      Select * 
      from Posts po
      Inner Join
      (
      Select CommentThread, CommentDate, CommentBody, Post from comments a
      inner join 
      (select commentthread, max(commentdate)
      from comments b
      group by commentthread)
      on a.commentthread = b.commentthread
      and a.commentdate = b.commentdate
      ) co
      on po.Post = co.post
      

      【讨论】:

      • 如果一个帖子不一定有 cmets 使用左外连接而不是帖子和 cmets 之间的内连接
      【解决方案3】:
       select *
         from post
            , comments
        where post.post_id = comments.post_id
          and comments.comments_id = (select max(z.comments_id) from comments z where z.post_id = post.post_id)
      

      【讨论】:

        【解决方案4】:

        如果你仍然坚持使用旧的 mysql 版本,它不知道子查询,你可以使用类似的东西

        选择
          p.id, c1.id
        从
          帖子为 p
        左连接
          cmets作为c1
        上
          p.id = c1.postId
        左连接
          cmets作为c2
        上
          c1.postId = c2.postId
          和 c1.id 无论哪种方式,请使用 EXPLAIN 检查您的查询是否存在性能问题。
            

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-17
          • 2011-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-13
          相关资源
          最近更新 更多