Get tree path in MySQL table -
perhaps easiest approach manage hierarchical data in mysql databases adjacency list model. is, give every node parent:
create table category( category_id int auto_increment primary key, name varchar(20) not null, parent int default null);
it easy parent node, or if there maximum tree depth, can whole tree using this:
select concat_ws('/', `t3`.`name`, `t2`.`name`, `t1`.`name`) `path` category t1 left join category t2 on t2.parent = t1.category_id left join category t3 on t3.parent = t2.category_id left join category t4 on t4.parent = t3.category_id t1.name = 'xxxxx';
that's enough in many cases, how can generalize solution trees deeper 3 nodes? i.e. may have path "electronics/audio/transmiter/fm/motorola".
is possible 1 query?
here's simple non recursive stored procedure job:
drop table if exists employees; create table employees ( emp_id smallint unsigned not null auto_increment primary key, name varchar(255) not null, boss_id smallint unsigned null, key (boss_id) ) engine = innodb; insert employees (name, boss_id) values ('f00',null), ('ali later',1), ('megan fox',1), ('jessica alba',3), ('eva longoria',3), ('keira knightley',5), ('liv tyler',6), ('sophie marceau',6); drop procedure if exists employees_hier; delimiter # create procedure employees_hier ( in p_emp_id smallint unsigned ) begin declare v_done tinyint unsigned default(0); declare v_dpth smallint unsigned default(0); create temporary table hier( boss_id smallint unsigned, emp_id smallint unsigned, depth smallint unsigned )engine = memory; insert hier select boss_id, emp_id, v_dpth employees emp_id = p_emp_id; /* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */ create temporary table emps engine=memory select * hier; while not v_done if exists( select 1 employees e inner join hier on e.boss_id = hier.emp_id , hier.depth = v_dpth) insert hier select e.boss_id, e.emp_id, v_dpth + 1 employees e inner join emps on e.boss_id = emps.emp_id , emps.depth = v_dpth; set v_dpth = v_dpth + 1; truncate table emps; insert emps select * hier depth = v_dpth; else set v_done = 1; end if; end while; select e.emp_id, e.name emp_name, p.emp_id boss_emp_id, p.name boss_name, hier.depth hier inner join employees e on hier.emp_id = e.emp_id left outer join employees p on hier.boss_id = p.emp_id; drop temporary table if exists hier; drop temporary table if exists emps; end # delimiter ; -- call sproc php call employees_hier(1);
Comments
Post a Comment