首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL选择查询

MySQL选择查询
EN

Stack Overflow用户
提问于 2011-01-09 18:43:15
回答 3查看 337关注 0票数 0

我在mysql中有一个巨大的员工数据,它有一个属性作为父id,它存储每个员工的主管,并以层次结构定义。每个用户都在其他员工的领导下工作,并处理4-5名成员的团队。我经常需要主管或下属树,我使用递归函数来获取其团队的雇员。请给我推荐一种方法,这样我就不必每次需要员工数据时都调用递归函数。使用“视图或存储过程”是个好主意吗?

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-09 19:14:59

当您使用存储过程时,仍然需要递归。您只需将递归从PHP源代码移动到数据库。

您可以使用nested sets来存储分层数据。这消除了递归,代价是插入、删除和重定位的成本更高。基本上,您创建了两个额外的字段leftright,其中left < righte1e2的下级of e1.left > e2.left && e1.right < e2.right

这使得SELECT查询很难读懂,但却很有效。在所有其他方法都失败的情况下执行此操作。

票数 0
EN

Stack Overflow用户

发布于 2011-01-09 19:32:52

下面是一个非递归存储过程实现,它显然只需要从应用程序代码中调用一次,而不需要n次调用(树的每一层都需要一个)。我建议远离嵌套的集合,坚持你的邻接表实现-想想 Oracle的连接和sql server中的CTE -不用再多说了。

代码语言:javascript
运行
复制
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 into 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 into hier select boss_id, emp_id, v_dpth from employees where 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 * from hier;

while not v_done do

    if exists( select 1 from employees e inner join hier on e.boss_id = hier.emp_id and hier.depth = v_dpth) then

        insert into hier select e.boss_id, e.emp_id, v_dpth + 1 
            from employees e inner join emps on e.boss_id = emps.emp_id and emps.depth = v_dpth;

        set v_dpth = v_dpth + 1;            

        truncate table emps;
        insert into emps select * from hier where depth = v_dpth;

    else
        set v_done = 1;
    end if;

end while;

select 
 e.emp_id,
 e.name as emp_name,
 p.emp_id as boss_emp_id,
 p.name as boss_name,
 hier.depth
from 
 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 this sproc from your php

call employees_hier(1);
票数 2
EN

Stack Overflow用户

发布于 2011-01-09 21:38:12

看看这些链接:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4638728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档