Php 论坛MySQL查询

Php 论坛MySQL查询,php,mysql,forum,Php,Mysql,Forum,我正在用CodeIgniter构建一个基本论坛,但我遇到了两个MySQL查询的问题 这是我的桌子: mysql> describe forum_posts; +----------+------------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +---

我正在用CodeIgniter构建一个基本论坛,但我遇到了两个MySQL查询的问题

这是我的桌子:

mysql> describe forum_posts;
+----------+------------------+------+-----+-------------------+----------------+
| Field    | Type             | Null | Key | Default           | Extra          |
+----------+------------------+------+-----+-------------------+----------------+
| id       | int(11) unsigned | NO   | PRI | NULL              | auto_increment |
| topic_id | int(11)          | YES  | MUL | NULL              |                |
| user_id  | int(11)          | YES  | MUL | NULL              |                |
| post     | text             | YES  |     | NULL              |                |
| date     | timestamp        | YES  |     | CURRENT_TIMESTAMP |                |
| ip       | varchar(15)      | YES  |     | NULL              |                |
+----------+------------------+------+-----+-------------------+----------------+
6 rows in set (0.01 sec)

mysql> describe forum_topics;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| category_id | int(11)          | YES  | MUL | NULL    |                |
| user_id     | int(11)          | YES  | MUL | NULL    |                |
| name        | varchar(100)     | YES  |     | NULL    |                |
| importance  | tinyint(2)       | YES  |     | 0       |                |
+-------------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql> describe forum_categories;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(50)      | YES  |     | NULL    |                |
| order | tinyint(2)       | YES  |     | 0       |                |
+-------+------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
1) 我想选择所有类别及其各自的最新帖子
2) 我想从id为X的类别中选择所有主题,并显示此主题中的最后一篇文章

这就是我到目前为止所做的

(1) :

(2) :

基本上,我的问题是我不能先对子查询排序,然后对它们进行分组


我也不确定这些任务是否足够有效。我正在处理子查询。他们会慢吗?

如果无法测试,我会尝试从这个想法开始。这可能不是别人会怎么做,但逻辑至少应该帮助你指明方向。我相信批评者会站出来,但你知道,没有人回答这个问题,所以我想我会努力让你朝着一个方向走

SELECT * FROM forum_categories $catArray ^^ SELECT p.*, t.* FROM forum_posts p, forum_topics t, forum_categories c WHERE t.category_id = c.id AND p.topic_id = t.id ORDER BY c.order ASC, p.date DESC GROUP BY t.id $postArray^^ for ($x = 0; $x < count($postArray); $x++) { for ($y = 0; $y < count($catArray); $y++) { if ($catArray[$y]['id'] == $postArray[$x]['category_id']) { $catData = $catArray[$y]; break; } } if ($catData['id'] != $currentCat) { PRINT CATEGORY >> $catData['name'] } PRINT TOPIC >> $postArray[$x]['name'] PRINT NEWEST POST >> $postArray[$x]['post'] $currentCat = $catData['id']; } 挑选* 从论坛类别 $catArray^^ 选择p.*,t* 来自论坛帖子p、论坛主题t、论坛类别c 其中t.category_id=c.id p.topic_id=t.id 按c.订单ASC、p.日期说明订购 按t.id分组 美元邮费^^ 对于($x=0;$x>$catData['name'] } 打印主题>>$postArray[$x]['name'] 打印最新帖子>>$postArray[$x]['POST'] $currentCat=$catData['id']; }
在我的头撞到墙上好几个小时后,我想我找到了(1)的解决方案,现在就更容易找到(2)的解决方案了

编辑:修复了(1)查询中的一个小错误,下面是(2)对于那些想要完成与我相同的任务的人:

SELECT 
    T.*,
    P.*

FROM forum_topics AS T

LEFT JOIN 
    (
        SELECT 
            P2.id AS post_id,
            P2.topic_id, 
            P2.user_id,
            P2.date,
            U.username
        FROM forum_posts AS P2
        LEFT JOIN users U ON U.id = P2.user_id
        ORDER BY P2.id DESC 
    )
    P ON P.topic_id = T.id 

WHERE T.category_id =  '1'
GROUP BY P.topic_id
ORDER BY P.topic_id DESC

这不会太慢的,谢谢。对于我的问题,您有什么解决方案吗?您打算如何布局数据?如果这是一个典型的论坛布局,那么你似乎已经做得太多了。类别可以自己进入一个名为/id的数组。主题查询可以访问该数组,同时显示查找类别的结果。您可以相应地对主题查询进行排序/排序。还有,您想要点什么和分组?按发布时间描述排序,按主题分组?如果这是预期的结果,似乎很简单。我试图列出所有类别和其中的最新帖子。编辑:事实上,你对单独查询类别的建议非常好。我将不得不单独获取包含最新帖子的主题,这似乎要容易得多。谢谢好建议!大多数论坛平台都没有标准化,它们的数据库结构做了某种预缓存。原因是大多数查询要么显示线程列表,要么显示来自特定线程的帖子列表。例如,为了“选择所有类别及其最新的帖子”,您应该在“FuruMySt目”表中考虑一个“LaxPyStIdID”列。这将大大简化查询并提高性能。另一个常见的例子是跟踪一个线程中的帖子数量,而不是在每次页面加载时计算每个线程的帖子数量。 SELECT * FROM forum_categories $catArray ^^ SELECT p.*, t.* FROM forum_posts p, forum_topics t, forum_categories c WHERE t.category_id = c.id AND p.topic_id = t.id ORDER BY c.order ASC, p.date DESC GROUP BY t.id $postArray^^ for ($x = 0; $x < count($postArray); $x++) { for ($y = 0; $y < count($catArray); $y++) { if ($catArray[$y]['id'] == $postArray[$x]['category_id']) { $catData = $catArray[$y]; break; } } if ($catData['id'] != $currentCat) { PRINT CATEGORY >> $catData['name'] } PRINT TOPIC >> $postArray[$x]['name'] PRINT NEWEST POST >> $postArray[$x]['post'] $currentCat = $catData['id']; }
SELECT 
    C.id,
    C.name AS category_name,
    C.order AS category_order,
    T.*

FROM forum_categories AS C

LEFT JOIN 
    (
        SELECT 
            T.category_id, 
            T.id AS topic_id, 
            T.name AS topic_name,
            P.user_id,
            P.username,
            P.date
        FROM forum_topics AS T

        LEFT JOIN
            (
                SELECT 
                    P2.id AS post_id,
                    P2.topic_id,
                    P2.user_id,
                    P2.date, 
                    U.username
                FROM forum_posts AS P2
                LEFT JOIN users AS U ON P2.user_id = U.id
                ORDER BY P2.id DESC
            )
            P ON P.topic_id = T.id

        ORDER BY P.post_id DESC
    )
    T ON T.category_id = C.id

GROUP BY C.id
SELECT 
    T.*,
    P.*

FROM forum_topics AS T

LEFT JOIN 
    (
        SELECT 
            P2.id AS post_id,
            P2.topic_id, 
            P2.user_id,
            P2.date,
            U.username
        FROM forum_posts AS P2
        LEFT JOIN users U ON U.id = P2.user_id
        ORDER BY P2.id DESC 
    )
    P ON P.topic_id = T.id 

WHERE T.category_id =  '1'
GROUP BY P.topic_id
ORDER BY P.topic_id DESC