【问题标题】:MySQL - how to show the latest topic per threadMySQL - 如何显示每个线程的最新主题
【发布时间】:2009-12-08 19:07:33
【问题描述】:

我正在尝试创建 SQL 来检索论坛线程的最新帖子列表。 我有以下代码:

SELECT
 item_discuss_thread_id
 , item_discuss_post_title
 , COUNT(item_discuss_thread_id) AS nb_posts
FROM
 item_discuss_posts
GROUP BY
 item_discuss_thread_id

显然,这将在不考虑帖子是否最新的情况下进行分组。 item_discuss_post_title 只会获得组中的第一行。

我想知道有没有办法解决这个问题?如果不是,解决问题的最佳方法是什么……只有子查询?

谢谢, 帕维尔

更新: 请注意,我需要所有线程,LIMIT 1 不能解决问题。 ORDER BY 也不是一个选项,因为 GROUP BY 无论如何都会从组中选择第一条记录。 这不是一个看起来那么简单的问题。

更新:

我真的想尽量避免使用子查询,或者如果这样做 - 尽可能使用它。 我目前带来的是这样的:

SELECT
  ordered_by_date.item_discuss_thread_id
  , item_discuss_post_title
  , COUNT(item_discuss_thread_id) AS nb_posts
FROM
  (
   SELECT
     item_discuss_thread_id
     , item_discuss_post_title
   FROM
      item_discuss_posts
   ORDER BY
      item_discuss_post_datetime DESC
  ) AS ordered_by_date
GROUP BY
   item_discuss_thread_id

EXPLAIN EXTENDED 给出以下结果:

id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1, PRIMARY, <derived2>, ALL, \N, \N, \N, \N, 20, Using temporary; Using filesort
2, DERIVED, item_discuss_posts, index, \N, item_discuss_post_datetime, 8, \N, 20, 

【问题讨论】:

  • 你想作为答案发布的那些 cmet 之一,但答案太简单了你也害怕!
  • 好吧,我不太了解 MySQL,所以我想也许我在这里遗漏了一些东西。另外,这似乎是一个显而易见的答案,我不敢相信 OP 会问它。
  • 我相信你们误解了这个问题。 ORDER BY 不会有任何区别,因为这里使用了 GROUP BY。
  • 这个怎么样:select max(item_discuss_thread_id), item_discuss_post_title from item_discuss_posts group by item_discuss_post_title
  • 不,这并没有什么意义。当然,您不能按标题分组,可能有很多具有相同标题的帖子。确实需要应用某种聚合,但我找不到适合的聚合

标签: mysql forum


【解决方案1】:

好的,我自己提出了解决方案。我使用了一个依赖子查询来解决。 这就是我的结果:

        SELECT
             item_discuss_threads.item_discuss_thread_id
             , item_discuss_threads.item_discuss_thread_datetime
             , item_discuss_threads.item_discuss_thread_title
             , latest_posts.item_discuss_post_title
             , latest_posts.item_discuss_post_datetime
             , COUNT(item_discuss_posts.item_discuss_post_id) AS nb_posts
        FROM
             item_discuss_threads
        INNER JOIN item_discuss_posts
             ON item_discuss_threads.item_discuss_thread_id=item_discuss_posts.item_discuss_thread_id
        INNER JOIN item_discuss_posts AS latest_posts
             ON latest_posts.item_discuss_thread_id=item_discuss_threads.item_discuss_thread_id
        WHERE
             (
                  SELECT
                        item_discuss_post_id
                  FROM
                        item_discuss_posts AS p
                  WHERE
                        p.item_discuss_thread_id=item_discuss_posts.item_discuss_thread_id
                  ORDER BY
                        item_discuss_post_datetime DESC
                  LIMIT
                       1
             )=latest_posts.item_discuss_post_id
        GROUP BY
             item_discuss_threads.item_discuss_thread_id
        ORDER BY
            latest_posts.item_discuss_post_datetime DESC

【讨论】:

    【解决方案2】:

    试试这个。

    SELECT
      *
    FROM
      (SELECT item_discuss_thread_id, item_discuss_post_title, COUNT(item_discuss_thread_id) AS nb_posts
       FROM item_discuss_posts
       ORDER BY __datecolumn__)
      AS ordered_by_date
    GROUP BY
      ordered_by_date.item_discuss_thread_id
    

    __datecolumn__替换为存储发布时间的列。

    【讨论】:

    • 谢谢。这行得通,尽管我认为这相当慢,但我正在寻找最佳解决方案。我想从这里的人们那里听到更多的想法——如果没有,我想我会坚持这样的想法。
    • 您能否在查询后面附加EXPLAIN EXTENDED 并将结果粘贴到另一条评论或问题提示中?如果您还没有这样做,您可能想要创建索引。
    • 问题不在于索引,而在于查询本身。 MySQL 将需要遍历所有帖子以首先按日期检索排序,然后再次遍历所有帖子以对其进行分组。此外,根据 SQL 标准,所有不是聚合的列都需要包含在 group by 语句中,否则结果是不可预测的。此 SQL 请求适用于当前的 MySQL 版本,但没有人保证它会在新版本上进一步工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    相关资源
    最近更新 更多