可能重复:
Is it possible to query a tree structure table in MySQL in a single query, to any depth?
我创建了一个管理区域,使用php从mysql数据库中提取数据并在表格中显示结果。基本上它显示父类别,然后是它下面的第一个子类别,然后是第三级子类别/主题。
它工作得很好但是因为我是mysql和php的新手我确信代码需要进行改进才能保存db资源,因为在构建表时我使用3循环并在每个循环中生成一个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>' ;
}
}
}
修改
好的,所以我做了一些研究,这就是我所在的地方:
对于一个小型数据库,我的方法很好。
对于使用数组来存储数据的更大的数据库可能意味着我需要使用可能耗尽太多内存的递归方法。很想听听人们的想法,它还会比在嵌套的while循环中循环db查询更好吗?
我找到了以下线程,其中有一个答案,没有递归和只有一个查询。不确定我是否需要在当前设计中添加位置列: How to build unlimited level of menu through PHP and mysql
如果我使用嵌套集模型而不是邻接模型重建设计,那么mysql查询将以所需的顺序返回结果,但是保持嵌套集的设计在我的头上并且我认为是过度的。
就是这样。如果有人有任何输入,请添加到对话中。必须有一个成功的方法,因为Web应用程序的负载必须满足这种要求。
答案 0 :(得分:1)
我认为你可以这样做:
SELECT * FROM categories
WHERE active = 'true'
ORDER BY parent_id, cat_id
这将为您提供按parent_id排序的所有类别,然后按cat_id排序。然后,您将获取结果集并从中构建多维数组。然后,您可以像现在一样循环遍历此数组,以便输出类别。
虽然从数据库访问角度来看这更好,但是由于需要将更大的数组保留在内存中,因此它也会占用更多内存。所以这真的是一个需要考虑的权衡。
答案 1 :(得分:0)
有很多问题需要解决,但我只会解决有关减少查询的问题。我建议一起删除WHERE子句并在while循环中使用if语句。使用外部变量来保存与特定条件匹配的所有结果,然后在循环后立即回显所有结果。这样的事情(为了简洁,我把一堆你的东西放在变量中)
//before loop
$firstInfoSet = '';
$secondInfoSet = '';
$thirdInfoSet = '';
//in while loop
if($parentID == NULL)
{
$firstInfoSet.= $yourFirstLineOfHtml;
}
if($active && $parentID == $catID) // good for query 2 and 3 as they are identical
{
$secondInfoSet.= $yourSecondLineOfHtml;
$thirdInfoSet.= $yourThirdLineOfHtml;
}
//after loop
echo $firstInfoSet . $secondInfoSet . $thirdInfoSet;
您现在可以制作任何类型的分组,如果需要可以轻松修改它们,并将结果放在任何地方。
- EDIT-- 在更好地理解了这个问题后......
$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
}
}