首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >统计所有直接或间接向经理汇报的下属。

统计所有直接或间接向经理汇报的下属。
EN

Stack Overflow用户
提问于 2013-07-26 10:27:53
回答 2查看 7.4K关注 0票数 4

我有一项任务有问题。

我需要统计所有直接或间接向某个经理汇报的下属(不同的)。

我有一个像这样的Employee表:

代码语言:javascript
复制
EMPLOYEE_ID Int,
MANAGER_ID Int,
EMPLOYEE_NAME varchar(200)

示例:

代码语言:javascript
复制
            Alex(1)
    --------------------
    Jhon(2)          Kevin(3)
------------------------------
Mike(4) Amanda(5)  Tom(6) Jery(7)

我只能计算直接向经理汇报的员工:

代码语言:javascript
复制
SELECT 
    MANAGER_ID
   ,COUNT(MANAGER_ID) as SubCount
FROM [dbo].[EMPLOYEE]
GROUP BY MANAGER_ID

但结果却是这样的:

代码语言:javascript
复制
Manager_ID | SubCount
----------------------
1          | 2
2          | 2
3          | 2
----------------------

相反:

代码语言:javascript
复制
Manager_ID | SubCount
----------------------
1          | 6
2          | 2
3          | 2
----------------------

我会很高兴有任何建议或想法如何做到这一点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-26 11:19:54

代码语言:javascript
复制
declare @t table(EMPLOYEE_ID Int,
MANAGER_ID Int,
EMPLOYEE_NAME varchar(200))
insert @t values(1,null,'Alex'),(2,1,'Jhon'),(3,1,'Kevin'),
(4,2,'Mike'),(5,2,'Amanda'),(6,3,'Tom'),(7,3,'Jerry')

;with a as
(
select EMPLOYEE_ID boss,EMPLOYEE_ID from @t t
  where exists (select 1 from @t where t.EMPLOYEE_ID = MANAGER_ID)
union all
select a.boss, t.EMPLOYEE_ID
from @t t join a on t.MANAGER_ID = a.EMPLOYEE_ID
)
--subtracting 1 because it is also counting the manager
select boss, count(*)-1 SubCount from a group by boss
option (maxrecursion 20)
票数 4
EN

Stack Overflow用户

发布于 2013-07-26 10:45:04

为此,需要使用递归CTE:

代码语言:javascript
复制
with managers as (
      select employee_id, manager_id, 1 as level
      from employees e
      union all
      select e.employee_id, m.manager_id, e.level+1
      from managers m join
           employees e
           on m.manager_id = e.employee_id
     )
select m.manager_id, count(*)
from managers m
group by m.manager_id;

递归CTE创建所有员工/经理对。最后一个查询执行聚合和计数。

编辑:

听起来,员工/经理之间的关系是有循环的。我认为以下修正了这个问题(我现在没有可用的SQL Server来测试它):

代码语言:javascript
复制
with managers as (
      select employee_id, manager_id, 1 as level
      from employees e
      union all
      select e.employee_id, m.manager_id, e.level+1
      from managers m join
           employees e
           on m.manager_id = e.employee_id
      where e.employee_id not in (select employee_id from managers)
     )
select m.manager_id, count(*)
from managers m
group by m.manager_id;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17878998

复制
相关文章

相似问题

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