Saturday, March 9, 2013

Procedure Hierarchical /recursive data (parent-child relationship)

drop table if exists product;

create table product
(
prod_id smallint unsigned not null auto_increment primary key,
name varchar(255) not null,
parent_id smallint unsigned null,
key (parent_id)
)engine = innodb;


insert into product (name, parent_id) values
('Products',null),
('Systems & Bundles',1),
('Components',1),
('Processors',3),
('Motherboards',3),
('AMD',5),
('Intel',5),
('Intel LGA1366',7);


delimiter ;

drop procedure if exists product_hier;

delimiter #

create procedure product_hier
(
in p_prod_id smallint unsigned
)
begin

declare v_done tinyint unsigned default 0;
declare v_depth smallint unsigned default 0;

create temporary table hier(
parent_id smallint unsigned,
prod_id smallint unsigned,
depth smallint unsigned default 0
)engine = memory;

insert into hier select parent_id, prod_id, v_depth from product where prod_id = p_prod_id;


create temporary table tmp engine=memory select * from hier;

while not v_done do

if exists( select 1 from product p inner join hier on p.parent_id = hier.prod_id and hier.depth = v_depth) then

insert into hier
select p.parent_id, p.prod_id, v_depth + 1 from product p
inner join tmp on p.parent_id = tmp.prod_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
p.prod_id,
p.name as prod_name,
b.prod_id as parent_prod_id,
b.name as parent_prod_name,
hier.depth
from
hier
inner join product p on hier.prod_id = p.prod_id
inner join product b on hier.parent_id = b.prod_id
order by
hier.depth, hier.prod_id;

drop temporary table if exists hier;
drop temporary table if exists tmp;

end #

delimiter ;

call product_hier(3);

call product_hier(5);


http://stackoverflow.com/questions/3812621/handling-tree-in-a-mysql-procedure


-------------===========-----------------=========------------------==========
same thing is modified by me in the form of FUNCTION recursive

drop function if exists product_hier;

delimiter #

create function product_hier
(
p_prod_id int
)
returns int

begin

declare v_done tinyint unsigned default 0;
declare v_depth smallint unsigned default 0;
declare v_check int;


create temporary table hier(
parent_id smallint unsigned,
prod_id smallint unsigned,
depth smallint unsigned default 0
)engine = memory;

insert into hier select parent_id, prod_id, v_depth from product where prod_id = p_prod_id;


create temporary table tmp engine=memory select * from hier;

while not v_done do

if exists( select 1 from product p inner join hier on p.parent_id = hier.prod_id and hier.depth = v_depth) then

insert into hier
select p.parent_id, p.prod_id, v_depth + 1 from product p
inner join tmp on p.parent_id = tmp.prod_id and tmp.depth = v_depth;

set v_depth = v_depth + 1;

delete from tmp;
insert into tmp select * from hier where depth = v_depth;

else
set v_done = 1;
end if;

end while;


set v_check= (select count(*) from
hier
inner join product p on hier.prod_id = p.prod_id
inner join product b on hier.parent_id = b.prod_id);


drop temporary table if exists hier;
drop temporary table if exists tmp;

return v_check ;
end #

delimiter ;



mysql> select product_hier(5);
mysql> select product_hier(24);





No comments:

Post a Comment

web stats