多级部门人数统计sql问题,急求

qq_34625790 2016-04-11 10:32:20
部门表 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
...全文
1346 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
surl61240 2018-04-23
  • 打赏
  • 举报
回复
可以一条语句搞定的: 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
slsu 2018-04-21
  • 打赏
  • 举报
回复
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
zhu19774279 2016-04-14
  • 打赏
  • 举报
回复
我们前两天也用到树形结构,因为要频繁访问,最后是在程序初始化的时候,把树形结构以多叉树的形式加载到内存里,每次在内存访问。
5446562 2016-04-13
  • 打赏
  • 举报
回复
引用 4 楼 ACMAIN_CHM 的回复:
MYSQL中仅用SQL语句无法实现,只能通过存储过程/函数,或者在外部程序中实现。 http://blog.csdn.net/acmain_chm/article/details/4142971 MySQL中进行树状所有子节点的查询 在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点。但很遗憾,在MySQL的目前版本中还没有对应的功能。 在MySQL中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度是4, 那么所有节点为根的树的深度均不会超过4,则我们可以直接通过left join 来实现。 但很多时候我们...
一级部门不要 单纯二级部门能搞定吧
5446562 2016-04-13
  • 打赏
  • 举报
回复
引用 5 楼 qq_34648581 的回复:
楼上正解,单纯sql搞不定,只能用过程了
一级部门不要 单纯二级部门能搞定吧
qq_34648581 2016-04-13
  • 打赏
  • 举报
回复
楼上正解,单纯sql搞不定,只能用过程了
ACMAIN_CHM 2016-04-12
  • 打赏
  • 举报
回复
MYSQL中仅用SQL语句无法实现,只能通过存储过程/函数,或者在外部程序中实现。 http://blog.csdn.net/acmain_chm/article/details/4142971 MySQL中进行树状所有子节点的查询 在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点。但很遗憾,在MySQL的目前版本中还没有对应的功能。 在MySQL中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度是4, 那么所有节点为根的树的深度均不会超过4,则我们可以直接通过left join 来实现。 但很多时候我们...
  • 打赏
  • 举报
回复
这种情况要写个函数,才能实现了。 给你一个例子做参考:

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)
qq_34625790 2016-04-11
  • 打赏
  • 举报
回复
有一个父级ID parentId 子部门的人数也要算在父级部门上面
qq_34625790 2016-04-11
  • 打赏
  • 举报
回复
mysql 数据库,不要存储过程

56,677

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧