部门表 depart 
KeyId varchar(50) 
DepartName varchar(200) 
ParentId varchar(50) 数据: 
AA001 总经办 root 
AB001 事业部 root
AA002 行政部 AA001 
AB002 客服部 AB001 
AB003 研发部 AB001 
AB004 支持部 AB002 人员表 people
KeyId int 
DepartID varchar(50)  所属部门 
 数据: 
1 AA001
2 AB001  
3 AA002 
4 AB002 
5 AB003 
6 AB004  
7 AB004  求统计各部门的人数,结果如下: 
AA001 总经办 2
AA002 行政部 1
AB001 事业部 6
AB002 客服部 2
AB003 研发部 1 
AB004 支持部 2

解决方案 »

  1.   

    mysql 数据库,不要存储过程
      

  2.   

    有一个父级ID parentId 子部门的人数也要算在父级部门上面
      

  3.   


    这种情况要写个函数,才能实现了。给你一个例子做参考:
    use world;
    create table if not exists tb(id int,name varchar(50),pid int,sort int,parent varchar(100),child varchar(100));insert into tb 
    values
    (1,'水果',0, null,null,null),
    (2,'热带水果',1,null,null,null),
    (3,'菠萝',2,null,null,null),
    (4,'香蕉',2,null,null,null),
    (5,'南美菠萝',3,null,null,null);
    drop function if exists getchildlist; /*
    1.
    本来是想要用while found_rows()>0 来判断的,
    因为select group_concat(id) into strChildT from tb where find_in_set(pid,strChildT) 
    如果group_concat(id) 为null时,也会返回1,所以修改为 while strChildT is not null.
    */
    CREATE DEFINER=`root`@`%` FUNCTION `getChildList`(idd int) RETURNS varchar(1000) CHARSET utf8
        READS SQL DATA
    begin
    declare strT varchar(1000);
        declare strChildT varchar(1000);    
        set strT = '$';                       /*初始化*/
        set strChildT = cast(idd as char);    /*凡事需要查找子节点的 父节点都会放到这里*/
     
        while strChildT is not null do
    set strT = concat(strT , ',' , strChildT); /*第一次的时候就是: $,idd */
            select group_concat(id) into strChildT from tb where find_in_set(pid,strChildT);
        end while;
        
    return strT;   /*返回: idd所有子节点的逗号间隔的字符串,包含idd节点本身*/
    end
    --2.显示当前id的所有子节点列表
    mysql> select *,getChildList(id) from tb;
    +------+----------+------+------+--------+-------+------------------+
    | id   | name     | pid  | sort | parent | child | getChildList(id) |
    +------+----------+------+------+--------+-------+------------------+
    |    1 | 水果     |    0 | NULL | NULL   | NULL  | $,1,2,3,4,5      |
    |    2 | 热带水果 |    1 | NULL | NULL   | NULL  | $,2,3,4,5        |
    |    3 | 菠萝     |    2 | NULL | NULL   | NULL  | $,3,5            |
    |    4 | 香蕉     |    2 | NULL | NULL   | NULL  | $,4              |
    |    5 | 南美菠萝 |    3 | NULL | NULL   | NULL  | $,5              |
    +------+----------+------+------+--------+-------+------------------+
    5 rows in set (0.03 sec)
    --3.查询节点1下面的所有子节点
    mysql> select * from tb where find_in_set(id,getChildList(1));
    +------+----------+------+------+--------+-------+
    | id   | name     | pid  | sort | parent | child |
    +------+----------+------+------+--------+-------+
    |    1 | 水果     |    0 | NULL | NULL   | NULL  |
    |    2 | 热带水果 |    1 | NULL | NULL   | NULL  |
    |    3 | 菠萝     |    2 | NULL | NULL   | NULL  |
    |    4 | 香蕉     |    2 | NULL | NULL   | NULL  |
    |    5 | 南美菠萝 |    3 | NULL | NULL   | NULL  |
    +------+----------+------+------+--------+-------+
    5 rows in set (0.16 sec)
      

  4.   

    MYSQL中仅用SQL语句无法实现,只能通过存储过程/函数,或者在外部程序中实现。http://blog.csdn.net/acmain_chm/article/details/4142971
    MySQL中进行树状所有子节点的查询
    在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点。但很遗憾,在MySQL的目前版本中还没有对应的功能。 在MySQL中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度是4, 那么所有节点为根的树的深度均不会超过4,则我们可以直接通过left join 来实现。 但很多时候我们...
      

  5.   

    楼上正解,单纯sql搞不定,只能用过程了
      

  6.   

    WITH RECURSIVE T AS (
        SELECT ds."keyId", ds."depName", ds."parentId",ds."keyId"||'' AS ID,ds."count" 
        FROM (SELECT d."keyId",d."depName",d."parentId",count(*) count,1 AS level FROM depart d,people p WHERE d."keyId"=p."departId"
    GROUP BY d."keyId",d."depName",d."parentId") ds
        WHERE "parentId"='root'    UNION     SELECT  d."keyId",d."depName", d."parentId",(ts.ID||','||d."keyId"),d."count"
        FROM (SELECT d."keyId",d."depName",d."parentId",count(*) count FROM depart d,people p WHERE d."keyId"=p."departId"
    GROUP BY d."keyId",d."depName",d."parentId")d
        JOIN T ts ON d."parentId" = ts."keyId"
        )
        SELECT d."keyId",d."depName",sum(t.count)  FROM T t ,depart d WHERE t.id like '%'||d."keyId"||'%' GROUP BY d."keyId",d."depName" ORDER BY d."keyId" ASC
      

  7.   

    可以一条语句搞定的:select aa.keyid,aa.DepartName,ifnull(bb.cnt,0) cnt
    from depart aa
    left join (select departid,count(1) cnt from people group by departid) bb on aa.keyid=bb.departid