【问题标题】:MySQL LEFT JOIN, INNER JOIN etc, complicated query, PHP + MySQL for a forumMySQL LEFT JOIN,INNER JOIN 等,复杂查询,PHP + MySQL for a forum
【发布时间】:2010-12-23 20:14:09
【问题描述】:

所以我有一个小论坛,我正在尝试获取数据,有 4 个表,forum、forum_posts、forum_threads 和 users。我想做的是获取每个论坛的最新帖子并让用户偷看该帖子,我还想获得每个论坛中的帖子数量和线程数量。另外,我想在一个查询中执行此操作。所以这就是我想出的:

SELECT lfx_forum_posts.*, lfx_forum.*, COUNT(lfx_forum_posts.pid) as posts_count,
    lfx_users.username,
    lfx_users.uid,
    lfx_forum_threads.tid, lfx_forum_threads.parent_forum as t_parent, 
    lfx_forum_threads.text as t_text, COUNT(lfx_forum_threads.tid) as thread_count
    FROM
    lfx_forum
    LEFT JOIN
    (lfx_forum_threads
        INNER JOIN
        (lfx_forum_posts
            INNER JOIN lfx_users
            ON lfx_users.uid = lfx_forum_posts.author)
        ON lfx_forum_threads.tid = lfx_forum_posts.parent_thread AND lfx_forum_posts.pid = 
                (SELECT MAX(lfx_forum_posts.pid)
                FROM lfx_forum_posts
                WHERE lfx_forum_posts.parent_forum = lfx_forum.fid
                GROUP BY lfx_forum_posts.parent_forum)
    )
    ON lfx_forum.fid = lfx_forum_posts.parent_forum
    GROUP BY lfx_forum.fid
    ORDER BY lfx_forum.fid ASC

这得到每个论坛的最新帖子,让我先睹为快,问题是

lfx_forum_posts.pid = 
                    (SELECT MAX(lfx_forum_posts.pid)
                    FROM lfx_forum_posts
                    WHERE lfx_forum_posts.parent_forum = lfx_forum.fid
                    GROUP BY lfx_forum_posts.parent_forum)

使我的 COUNT(lfx_forum_posts.pid) 变为一个(以及 COUNT(lfx_forum_threads.tid) 这不是我希望它工作的方式。我的问题是:有一些简单的方法可以让它显示正确的号码,同时获取正确的帖子信息(最新的)?

如果有什么不清楚的地方请告诉我,我会尝试进一步解释我的问题,这是我第一次在这里发帖。

【问题讨论】:

    标签: php mysql forum


    【解决方案1】:

    仅通过一个这样的大查询很难了解表的结构。 您是否考虑过制作视图以更轻松、更快速地运行查询? 为什么必须将其保留在一个查询中?就我个人而言,我发现您通常可以通过将过于复杂的查询拆分为更多部分来获得性能和代码可读性。

    但很难得到一个概述,所以不能很好地回答你的问题:)

    【讨论】:

    • 什么是视图,我可以在 phpmyadmin 中创建它,或者我将如何使用 mysql-prompt 来实现它?我在想的是,如果我不能在一两个查询中做到这一点,我将不得不对所有数据进行大量的 foreach 循环,这是我之前辞职的。我希望一个大查询会更快,因为 mysql 可以做一些优化等等?如果我使用两个查询和一个 foreach 循环,我会注意到速度上有很大差异吗?提前致谢!
    • 视图是基于一个或多个表的数据的虚拟表。这样,如果您有多个包含不同数据的表,您可以创建一个视图来保存每行所需的数据。然后,您可以查询视图而不是原始表。在这里找到了一个教程mysqltutorial.org/mysql-views-tutorial.aspx
    • 谢谢,我会尽力调查的!现在,我通过部分使用此查询并按照 oyatek 所说的添加 num_posts 对其进行了排序。
    【解决方案2】:

    只需将num_posts 列添加到您的表中。不要用 COUNT() 计算帖子。

    【讨论】:

    • 我应该将它添加到我的论坛表格中,然后从那里选择它,然后每次我添加帖子时更新它吗?为什么计数不好?
    • 1) "select num_posts from forums where id=25" 比 "select count(post_id) as num_posts from forum_posts where forum_id=25" 快 2) 更容易阅读 - 只需选择一列,无需编写过多的代码...我总是使用列 num_... 而不是 count() 在可能的情况下。是的,只需将此列添加到您需要计数器的每个表中。你也可以添加触发器,你的计数器会自动增加。
    【解决方案3】:

    我们可以买一些吗...

    Show Tables;
    Desc Table lfx_forum_posts;
    Desc Table lfx_forum_threads;
    Desc Table lfx_forum_users;
    Desc Table lfx_forum;
    

    这是一些伪代码

    select f.*, (select count(*) from forum_posts fp where fp.forum_id =  f.id) as num_posts,
    (select count(*) from forum_threads ft where ft.forum_id =  f.id) as num_threads,
    (select max(fp.id) from forum_posts fp  
    where fp.id = f.id
    ) as latest_post_id,
    from forums f;
    

    然后继续在单独的查询中使用 latest_post_id 来获取它的信息。

    如果它在声明之前不喜欢使用 f,则为此创建一个临时表,然后每次运行查询时更新。

    【讨论】:

    • 真的没想到会那样做,谢谢!不过只是一个想法:当我的规模很小时,是否像 oyatek 所说的那样做更快,只去一个名为 num_posts 和 num_threads 的列?或者我应该从一开始就使用 count() 吗?
    猜你喜欢
    • 1970-01-01
    • 2018-07-10
    • 2015-11-29
    • 1970-01-01
    • 2012-09-10
    • 2016-12-14
    • 2015-01-10
    • 2021-10-20
    • 1970-01-01
    相关资源
    最近更新 更多