开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜