Recursive function for category and sub-category
I need help regarding recursive function We have a category table contains category_id,category_name and parent_id:
category_id category_name parent_id
------------+--------------+----------
1 Agriculture 0
2 Appearl & Fashion 0
3 Chemicalas 0
4 Plastic & Plastic Products 0
5 Automobile 0
14 Coconut Shell Products 1
15 Nuts & Kernels 1开发者_Python百科
16 Plant & Animal Oil 1
17 Potpourri 1
18 Raw Cotton & Cotton Waste 1
19 Rice 1
20 Tea 1
21 Seeds 1
22 Vegetable 1
23 White Rice 19
24 Green Rice 19
25 Basmati Rice 19
26 Boiled Rice 19
27 Fresh Preserved Vegetables 22
28 Frozen & Dried Vegetables 22
29 Others 22
30 Activated Carbon 3
We want the output of the category like below using recursive function:
Agriculture > Rice > White rice
Agruculture > Rice > Basmati rice
pls. guide and help me
Although it is not quite the same schema you have for the table, this article is very useful for doing something very similar to what it seems you are trying to do. Have a read and see what you think, it really helped me the first time I tried doing a tree structure like yours.
Fairly simple to do in a single call from PHP to MySQL using a non-recursive/adjacency list stored procedure implementation.
Hope it helps :)
Example calls
mysql> call category_hier(1);
+--------+---------------+---------------+----------------------+-------+
| cat_id | category_name | parent_cat_id | parent_category_name | depth |
+--------+---------------+---------------+----------------------+-------+
| 1 | Location | NULL | NULL | 0 |
| 3 | USA | 1 | Location | 1 |
| 4 | Illinois | 3 | USA | 2 |
| 5 | Chicago | 3 | USA | 2 |
+--------+---------------+---------------+----------------------+-------+
4 rows in set (0.00 sec)
mysql> call category_hier(2);
+--------+---------------+---------------+----------------------+-------+
| cat_id | category_name | parent_cat_id | parent_category_name | depth |
+--------+---------------+---------------+----------------------+-------+
| 2 | Color | NULL | NULL | 0 |
| 6 | Black | 2 | Color | 1 |
| 7 | Red | 2 | Color | 1 |
+--------+---------------+---------------+----------------------+-------+
3 rows in set (0.00 sec)
$sqlCmd = sprintf("call category_hier(%d);", 1);
$sqlCmd = sprintf("call category_hier(%d);", 2);
Tables and Test data
drop table if exists categories;
create table categories
(
cat_id smallint unsigned not null auto_increment primary key,
name varchar(255) not null,
parent_cat_id smallint unsigned null,
key (parent_cat_id)
)
engine = innodb;
insert into categories (name, parent_cat_id) values
('Location',null),
('Color',null),
('USA',1),
('Illinois',3),
('Chicago',3),
('Black',2),
('Red',2);
Stored procedure
drop procedure if exists category_hier;
delimiter #
create procedure category_hier
(
in p_cat_id smallint unsigned
)
begin
declare v_done tinyint unsigned default 0;
declare v_depth smallint unsigned default 0;
create temporary table hier(
parent_cat_id smallint unsigned,
cat_id smallint unsigned,
depth smallint unsigned default 0
)engine = memory;
insert into hier select parent_cat_id, cat_id, v_depth from categories where cat_id = p_cat_id;
create temporary table tmp engine=memory select * from hier;
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
while not v_done do
if exists( select 1 from categories c
inner join hier on c.parent_cat_id = hier.cat_id and hier.depth = v_depth) then
insert into hier select c.parent_cat_id, c.cat_id, v_depth + 1 from categories c
inner join tmp on c.parent_cat_id = tmp.cat_id and tmp.depth = v_depth;
set v_depth = v_depth + 1;
truncate table tmp;
insert into tmp select * from hier where depth = v_depth;
else
set v_done = 1;
end if;
end while;
select
c.cat_id,
c.name as category_name,
p.cat_id as parent_cat_id,
p.name as parent_category_name,
hier.depth
from
hier
inner join categories c on hier.cat_id = c.cat_id
left outer join categories p on hier.parent_cat_id = p.cat_id
order by
hier.depth;
drop temporary table if exists hier;
drop temporary table if exists tmp;
end #
delimiter ;
Something like?
function recursiveCategory($categoryId) {
// Some code to get category from the database resulting in Category-array
$content = $Category["category_name"];
if($Category["category_parent"] == 0) {
$content .= " > ".$recursiveCategory($Category["category_parent"]);
}
return $content;
}
Also, don't use the value 0 in parent_id if the category does not have a parent. Use null
instead.
精彩评论