MySQL 将论坛及其子论坛分组到同一组中,然后再执行每组最大 n 项操作

标签 mysql greatest-n-per-group categories

在网页上,我想显示论坛列表 (parent_id = 0) 对于每个论坛,显示该论坛及其子论坛组中最新(最新)的 3 个主题

APPLE (Forum)
 iPad3        Apr 12   (Topic from subForum "Tablets")
 Genius Bar   Apr 11   (Topic from Forum "APPLE")
 iPodNano     Apr 10   (Topic from subForum "Portables")
repeat with next forum

MySQL 5.5结构

table FORUMS (contains Forums and subForums, 2 level hierarchy max)
 id (autoinc)
 parent_id (0 if Forum, link to other rows id if subForum)
 name


table TOPICS (a Topic is a child of Forums or subForums)
 id (autoinc)
 forum_id (linked to FORUMS table
 name
 date_added (datetime)

我可以通过简单的查询将论坛的结果集放入 PHP 中的数组中并循环遍历该数组。

我不知道如何创建显示前 3 个主题的第二个结果集。

我已经阅读了有关 Greatest-N-Per-Group 的帖子,并尝试过它们,但我认为我的想法增加了一定程度的复杂性。我的大脑现在很困惑,所以我寻求帮助。

我是否创建一个 mysql 变量来保存论坛 id 及其子论坛的 id 的逗号分隔列表,然后将其用作 IN (1, 4, 6) 语句的值?

或者这是一个糟糕的设计/想法并且执行成本太高?

我读过很多关于 SO 的相关帖子,但是您也可以指向我的任何链接我也会阅读。

最佳答案

由于您的问题不够清晰,我不得不做出一些假设,但您应该能够修改它以适合您的表/字段名称。我在最里面的查询中包含了一个基于日期的过滤器,以尝试减少开销。您可能需要修改 topics.date_added >(CURRENT_DATE - INTERVAL 1 MONTH) 标准,以确保每个论坛组始终有 3 个条目 -

SELECT *
FROM (
    SELECT
        tmp.*,
        @rank := IF(@forum=forum_id, @rank + 1, 1) rank, 
        @forum := forum_id
    FROM (
        SELECT
            forums.id AS forum_id,
            forums.name AS forum_name,
            NULL AS subforum_id,
            NULL AS subforum_name,
            topics.name AS topic_name,
            topics.date_added
        FROM forums
        INNER JOIN topics
            ON (forums.id = topics.forum_id)
        WHERE topics.date_added > (CURRENT_DATE - INTERVAL 1 MONTH)
        AND forums.parent_id = 0
        UNION ALL
        SELECT
            forums.id AS forum_id,
            forums.name AS forum_name,
            subforums.id AS subforum_id,
            subforums.id AS subforum_name,
            topics.name AS topic_name,
            topics.date_added
        FROM forums
        INNER JOIN forums subforums
            ON forums.id = subforums.parent_id
        INNER JOIN topics
            ON subforums.id = topics.forum_id
        WHERE topics.date_added > (CURRENT_DATE - INTERVAL 1 MONTH)
        AND forums.parent_id = 0
        ORDER BY forum_id ASC, date_added DESC
    ) tmp, (SELECT @forum:=NULL, @rank:=NULL) initvars
) tmp2
WHERE rank <= 3

注意:我没有尝试过,因此可能存在语法错误。

关于MySQL 将论坛及其子论坛分组到同一组中,然后再执行每组最大 n 项操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10133068/

相关文章:

mysql - 使用 GROUP BY 仅对某些行进行分组

sql - 如何选取每组的前N行?

sql - 为表中的每个ID选择最新的3条记录

php - magento 类别未显示在添加产品页面上?

mysql - Laravel:循环并显示多个计数

php - 在数据不可用时显示年度报告(CI、PHP、MySQL)

php - ezpublish 5.4 根据父字段排序

MySQL 只选择多余的行而忽略原来的行

objective-c - Objective-C中的继承和类别有什么区别

iphone - 在实现文件中使用类别作为私有(private)方法?