php mysql是在循环中再次使用相同查询的替代方案

php mysql是在循环中再次使用相同查询的替代方案,php,mysql,hierarchical-data,nested-sets,Php,Mysql,Hierarchical Data,Nested Sets,可能重复: 我创建了一个管理区域,它使用php从mysql数据库中提取数据,并将结果显示在表中。基本上,它显示一个父类别,然后是它下面的第一个子类别,然后是第三级子类别/主题 它工作得很好,但由于我是mysql和php新手,我确信代码需要改进,以便在构建表时节省db资源。我使用3个while循环,在每个循环中创建一个mysql查询,我确信这样做是错误的 有人能帮我找到最好的方法吗 代码如下: $query = mysql_query("SELECT * FROM cate

可能重复:

我创建了一个管理区域,它使用php从mysql数据库中提取数据,并将结果显示在表中。基本上,它显示一个父类别,然后是它下面的第一个子类别,然后是第三级子类别/主题

它工作得很好,但由于我是mysql和php新手,我确信代码需要改进,以便在构建表时节省db资源。我使用3个while循环,在每个循环中创建一个mysql查询,我确信这样做是错误的

有人能帮我找到最好的方法吗

代码如下:

           $query = mysql_query("SELECT * FROM categories WHERE
parent_id is null
order by cat_id asc;", $hd)
or die ("Unable to run query");       

while ($row = mysql_fetch_assoc($query)) {
echo '<tr style="font-weight:bold;color:green;"><td>'. $row    ['cat_id'].'</td><td>'.$row['cat_name'].'</td><td>'.$row    ['parent_id'].'</td><td>'.$row['active'].'</td><td>'.$row    ['url'].'</td><td>'.$row['date_updated'].'</td></tr>' ;

$query2 = mysql_query("SELECT * FROM categories WHERE
                (active = 'true' AND parent_id = ".$row    ['cat_id'].")
                order by cat_id asc;", $hd)
      or die ("Unable to run query");
while ($row2 = mysql_fetch_assoc($query2)) {
echo '<tr style="font-weight:bold;"><td>'. $row2['cat_id'].'</td><td>'.$row2    ['cat_name'].'</td><td>'.$row2['parent_id'].'</td><td>'.$row2    ['active'].'</td><td>'.$row2['url'].'</td><td>'.$row2    ['date_updated'].'</td></tr>' ;
    $query3 = mysql_query("SELECT * FROM categories WHERE
                (active = 'true' AND parent_id = ".$row2    ['cat_id'].")
                order by cat_id asc;", $hd)
      or die ("Unable to run query");
      while ($row3 = mysql_fetch_assoc($query3)) {
echo '<tr><td>'. $row3['cat_id'].'</td><td>'.$row3['cat_name'].'</td><td>'.$row3    ['parent_id'].'</td><td>'.$row3['active'].'</td><td>'.$row3    ['url'].'</td><td>'.$row3['date_updated'].'</td></tr>' ;

}
}
}
$query=mysql\u query(“从类别中选择*,其中
父项id为空
由cat_id asc订购;“,$hd)
或死亡(“无法运行查询”);
while($row=mysql\u fetch\u assoc($query)){
回显“.$row['cat\u id'..”.$row['cat\u name'..”.$row['parent\u id'..”.$row['active'.'。$row['url'.'。$row['date\u updated'.]”;
$query2=mysql\u query(“从类别中选择*,其中
(active='true'和parent_id=“.$row['cat_id']))
由cat_id asc订购;“,$hd)
或死亡(“无法运行查询”);
while($row2=mysql\u fetch\u assoc($query2)){
回显'.$row2['cat_id'.'.'.$row2['cat_名称'.'.'.'.$row2['parent_id'.'.'.'.$row2['url'.'.'.$row2['date_updated'.'';
$query3=mysql\u query(“从类别中选择*,其中
(active='true'和parent_id=“.row2['cat_id']))
由cat_id asc订购;“,$hd)
或死亡(“无法运行查询”);
while($row3=mysql\u fetch\u assoc($query3)){
回显'.$row3['cat_id'.'.'.$row3['cat_名称'.'.'.'.$row3['parent_id'.'.'.'.$row3['url'.'.'.$row3['date_updated'.'';
}
}
}
编辑

好的,我做了一些研究,这就是我的工作:

可能对于一个小型数据库,我的方法很好

对于更大的数据库,使用数组存储数据可能意味着我需要使用递归方法,这可能会占用太多内存。我很想听听人们的想法,它是否仍然比在嵌套的while循环中循环db查询更好

我发现了下面的线程,其中有一个答案,可以不用重新命名,只需一个查询就可以完成这项任务。不确定是否需要在当前设计中添加职位栏:

如果我使用嵌套集模型而不是邻接模型重新构建设计,那么mysql查询将按要求的顺序返回结果,但是维护嵌套集设计是我所不能理解的,我认为这太过分了


就这样。如果有人对此有任何意见,请添加到对话中。必须有一个成功的方法,因为这种需求对于大量的web应用程序来说是必需的。

我认为您可以这样做:

SELECT * FROM categories
WHERE active = 'true'
ORDER BY parent_id, cat_id
这将为您提供按父类id排序的所有类别,然后按类别id排序。然后您将获取结果集并从中构建多维数组。然后,您可以像当前一样循环这个数组,以便输出类别


虽然从DB访问的角度来看这更好,但它也会消耗更多内存,因为您需要在内存中保留这个更大的阵列。所以这确实是一个你需要考虑的权衡。

< P>我想你能做这样的事情:

SELECT * FROM categories
WHERE active = 'true'
ORDER BY parent_id, cat_id
这将为您提供按父类id排序的所有类别,然后按类别id排序。然后您将获取结果集并从中构建多维数组。然后,您可以像当前一样循环这个数组,以便输出类别


虽然从DB访问的角度来看这更好,但它也会消耗更多内存,因为您需要在内存中保留这个更大的阵列。所以,这确实是一个需要考虑的权衡。

有很多要解决的地方,但是我只想谈谈关于减少查询的问题。我建议将WHERE子句全部去掉,并在while循环中使用if语句。使用外部变量保存与特定条件匹配的所有结果,然后在循环后立即回显所有结果。类似这样的东西(为了简洁起见,我把你的一些东西放在变量中)

现在,您可以创建任何类型的分组,如果需要,可以轻松修改它们,并将结果放在任何您想要的地方

--编辑-- 在更好地理解这个问题之后

$query = mysql_query("SELECT * FROM categories order by cat_id asc;", $hd);
$while ($row = mysql_fetch_assoc($query)){
   if($row['parent_id'] == NULL){
      //echo out your desired html from your first query 
   }
   if($row['active'] && $row['parent_id']== $row['cat_id']){
      //echo out your desired html from your 2nd and 3rd queries
   }
}

这里有很多问题需要解决,但我将只回答您关于减少查询的问题。我建议将WHERE子句全部去掉,并在while循环中使用if语句。使用外部变量保存与特定条件匹配的所有结果,然后在循环后立即回显所有结果。类似这样的东西(为了简洁起见,我把你的一些东西放在变量中)

现在,您可以创建任何类型的分组,如果需要,可以轻松修改它们,并将结果放在任何您想要的地方

--编辑-- 在更好地理解这个问题之后

$query = mysql_query("SELECT * FROM categories order by cat_id asc;", $hd);
$while ($row = mysql_fetch_assoc($query)){
   if($row['parent_id'] == NULL){
      //echo out your desired html from your first query 
   }
   if($row['active'] && $row['parent_id']== $row['cat_id']){
      //echo out your desired html from your 2nd and 3rd queries
   }
}

谢谢你的回答,我不确定我是否理解。从我所能理解的情况来看,当我需要显示父ID时,我似乎只会一个接一个地显示每个信息集,然后显示该ID下的第一个子类别,然后遍历该ID下的子类别(第三级),然后当它们结束时,检查该父ID下是否有更多类别,等等。。。不确定一次将其全部舍入是否可以做到这一点?抱歉,没有注意到whiles是嵌套的。只需在每个if语句中添加回显行。不需要把他们分组。好的,我想我明白了。你是说我应该访问数据库一次,然后遍历结果?如上所述,这将使用更多内存,而且我还需要将其全部放在一个数组中,因为使用mysql\u fetch\u assoc将无法工作,因为我需要不断地上下查看结果行。也许我误解了?你一直都是