如何在没有循环查询的情况下获取类别树?

时间:2014-08-03 13:46:46

标签: php mysql sql recursion

我有这个问题:

$query='select id, bg_category from products_categories where 
visible="1" and parent="0" group by bg_category order by bg_category ASC';    

你可以从这一点开始成像我将$ num_rows循环到子类别而不是它的子类别..它仍在工作,因为类别的数量低于20.但现在类别超过130这种方式生成类别树是浪费服务器resoure ..我现在正在考虑改变这个并寻找将只执行1个查询的php解决方案。我在这里找到了这个:Build a tree from a flat array in PHP但无法理解/使其有效:

$q = mysql_query("SELECT id, parent_id, name FROM categories");
while ($r = mysql_fetch_row($q)) {
$names[$r[0]] = $r[2];
$children[$r[0]][] = $r[1];
}

function render_select($root=0, $level=-1) {
global $names, $children;
if ($root != 0)
echo '<option>' . strrep(' ', $level) . $names[$root] . '</option>';
foreach ($children[$root] as $child)
render_select($child, $level+1);
}

echo '<select>';
render_select();
echo '</select>';

以上这个怎么样?我需要传递给render_select(); ?

此外,如果此解决方案有效,它是否会节省服务器资源而不是循环查询? 提前感谢您的帮助

编辑: 我的数据库具有以下类别结构:

#id        #bg_category      #parent
1          electronics         0
2          Phones              1
3          Smartphones         2
4          normalphones        2

输出如下:

<ul>
<li>electronics
<ul class="sublevel">
<li>Phones
<ul><li>Smartphones</li>
</ul></li></ul></li>
</ul>

等等。希望这有帮助

1 个答案:

答案 0 :(得分:0)

如果它总是最多2级,您可以使用下面的查询。在php中,您可以检查当前行上的bg_category是否与上一行中的bg_category相同,以显示或不显示列,与child1相同,因为它们可以有多个child2。

为了说明,我添加了一些其他类别和子类别,以便进行说明。

我使用3个下划线表示1个深度,6个下划线表示2个深度,但实际上可以将一些html标记放入sql中,以便为您生成每个级别的内容。

这应该可以工作,尽管数据库中的行的顺序 - 由id字段确定 - 但就像我说它只能工作2级深。

虽然看起来很糟糕,但您可以设置一些视图来简化您实际运行的查询。当然,这仍然假设你只有2级深度。如果你在子类别的子类别上有子类别,则可能不是sql。

<强>小提琴: http://sqlfiddle.com/#!2/630c6/18/0

select w.bg_category, w.child, x.child as child2

from(

select x.bg_category, y.bg_category as child

from(

select id, bg_category, parent
from tbl
where parent = 0
union all
select id, concat('___',bg_category), parent
from tbl
where id in (select parent id from tbl)
and parent <> 0
union all
select id, concat('______',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent not in (select id from tbl where parent = 0)
union all
select id, concat('___',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent in (select id from tbl where parent = 0)

  ) x

join

(

  select id, bg_category, parent
from tbl
where parent = 0
union all
select id, concat('___',bg_category), parent
from tbl
where id in (select parent id from tbl)
and parent <> 0
union all
select id, concat('______',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent not in (select id from tbl where parent = 0)
union all
select id, concat('___',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent in (select id from tbl where parent = 0)

  ) y on x.id = y.parent

  ) w

left join

(

select x.bg_category, y.bg_category as child

from(

select id, bg_category, parent
from tbl
where parent = 0
union all
select id, concat('___',bg_category), parent
from tbl
where id in (select parent id from tbl)
and parent <> 0
union all
select id, concat('______',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent not in (select id from tbl where parent = 0)
union all
select id, concat('___',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent in (select id from tbl where parent = 0)

  ) x

join

(

  select id, bg_category, parent
from tbl
where parent = 0
union all
select id, concat('___',bg_category), parent
from tbl
where id in (select parent id from tbl)
and parent <> 0
union all
select id, concat('______',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent not in (select id from tbl where parent = 0)
union all
select id, concat('___',bg_category), parent
from tbl
where id not in (select parent from tbl)
and parent in (select id from tbl where parent = 0)

  ) y on x.id = y.parent

  ) x on w.child = x.bg_category

where substr(w.bg_category,1,1) <> '_'