如何从循环中删除此查询?

时间:2010-04-02 20:46:17

标签: php mysql loops

我目前正在设计一个论坛作为个人项目。我遇到的一个反复出现的问题是循环中的数据库查询。到目前为止,我已经设法避免使用表连接或数组中的数据缓存以供以后使用。

现在虽然我遇到过一种情况,我不确定如何以这样的方式编写代码,以至于我可以轻松地使用这些方法中的任何一种。但是我仍然更愿意为此操作最多进行2次查询,而不是每组论坛1 + 1,到目前为止每页有5次。所以虽然5不是一个庞大的数字(虽然它会为我添加的每个论坛组增加)但这是对我来说很重要的原则,我不想在循环中编写查询

我正在做的是显示论坛索引分组(例如管理论坛,用户论坛等),然后在单个页面索引上显示该组内的每个论坛,这是两个在一个页面中的组合导致我的问题。如果每页只有一个组,我会使用表连接并解决问题。但是如果我在这里使用表连接,虽然我可以获得我需要的所有数据,但它将在一个大量的结果中并且需要正确显示。

这是代码(我为了清晰起见删除了一些html)

<?php
    $sql= "select * from forum_groups"; //query 1
    $result1 = $database->query($sql);
    while($group = mysql_fetch_assoc($result1)) //first loop
      {?>
        <table class="threads"> 
        <tr>
              <td class="forumgroupheader"> <?php echo $group['group_name']; ?> </td>
            </tr>
            <tr> 
          <td class="forumgroupheader2"> <?php echo $group['group_desc']; ?> </td>
            </tr>
       </table>
       <table>
        <tr>
        <th class="thforum"> Forum Name</th>
        <th class="thforum"> Forum Decsription</th>
        <th class="thforum"> Last Post </th>
        <tr>
            <?php 

                $group_id = $group['id'];
                $sql = "SELECT forums.id, forums.forum_group_id, forums.forum_name, forums.forum_desc, forums.visible_rank, forums.locked, forums.lock_rank, forums.topics, forums.posts, forums.last_post, forums.last_post_id, users.username
FROM forums 
LEFT JOIN users on forums.last_post_id=users.id 
WHERE forum_group_id='{$group_id}'";
                //query 2
                $result2 = $database->query($sql);
                while($forum = mysql_fetch_assoc($result2))
                                            //second loop        
                    {?>

那我该怎么办呢  a)以这样的方式编写SQL,以便从循环内部删除第二个查询或者  b)将结果组合成阵列
无论哪种方式,我都需要能够像以前那样访问数据,因此我可以为页面输出正确地格式化它,即在循环内仍然。

2 个答案:

答案 0 :(得分:3)

您可以使用两个查询执行此操作。第一个查询不需要更改(虽然我个人不想使用SELECT *)。在开始迭代之前,应该更改第二个查询以加入forum_groups并在循环外运行:

SELECT forum_groups.id, ...other columns here...
FROM forum_groups 
JOIN forums ON forum_groups.id = forum_group_id
LEFT JOIN users ON forums.last_post_id = users.id

您还可以将这两个查询合并为一个大型查询,一次性获取所有数据,但我可能不会这样做,因为它需要返回冗余数据。

答案 1 :(得分:2)

我认为你的做法不是很糟糕,我不会改变它。但是,作为练习,如果您选择论坛(与组合并)并按组ID排序,则可以在一个查询中完成所有操作。这样你只做了一个选择,你就可以开始循环了。在循环中,您将检查group_id是否已更改。如果有,则开始一个新的组头。

如果这是一个超高流量网站,您还可以查看缓存,以便在构建完网页后将其写入磁盘。

以下是您如何检测群组变化的示例:

$currentGroupId = 0;
$firstTime = true;
while ($row = mysql_query_fetch_assoc($res)) {
    if ($row['group_id'] != $currentGroupId) {
        $currentGroupId = $row['group_id'];
        if (!$firstTime) {
            // echo close group html
        } else {
            $firstTime = false;
        }
        // echo open group html
    }

    // do forum stuff
}
// echo close group html