如何找到每个经理下的所有员工

Posted

技术标签:

【中文标题】如何找到每个经理下的所有员工【英文标题】:how to find all employees under each manager 【发布时间】:2016-01-30 19:53:59 【问题描述】:

我需要查询以显示从一位特定经理开始一直向下的下属。假设我有这个结构,我需要让所有员工从 ManagerId = 1 开始

EmployeeId  ManagerId
2           1
3           1 
4           3
5           3 
6           4

我需要获取 ManagerId 和他下属的直接下属员工及其下属的查询结果。

例如,使用 SQL Server 2014:

CREATE TABLE #Pepe (EmployeeId INT, ManagerId int)

INSERT INTO [#Pepe] ( [EmployeeId], [ManagerId] ) VALUES  (2, 1)
INSERT INTO [#Pepe] ( [EmployeeId], [ManagerId] ) VALUES  (3, 1)
INSERT INTO [#Pepe] ( [EmployeeId], [ManagerId] ) VALUES  (4, 3)
INSERT INTO [#Pepe] ( [EmployeeId], [ManagerId] ) VALUES  (5, 3)
INSERT INTO [#Pepe] ( [EmployeeId], [ManagerId] ) VALUES  (6, 4)

现在我得到了 CTE

;WITH relation AS 
    (
       SELECT 1 as EmployeeId,  0 AS LEVEL

       UNION ALL

       SELECT r.EmployeeId, LEVEL + 1 AS LEVEL
         FROM (SELECT EmployeeId, ManagerId FROM #Pepe) r
        INNER JOIN relation T 
           ON r.ManagerId = T.EmployeeId
        WHERE r.ManagerId <> r.EmployeeId 

    )  

SELECT DISTINCT  EmployeeId, LEVEL FROM relation 

我的 CTE 结果是这样的:

EmployeeId  LEVEL
1           0
2           1 
3           1
4           2
5           2
6           3

这个结果从一个特定的员工开始,它是 1(在 CTE 上硬编码),现在我只需要直接下属,级别 = 1 以及级别 0,即员工 ID 1、2 和 3。

这很好,现在我需要的是每个员工 id(0 级和 1 级),我需要得到这个结果:

EmployeeId  ManagerId
1           1
2           1
3           1
4           1
5           1
6           1
2           2
3           3
4           3
5           3
6           3

如您所见,Manager Id 包含级别 0 和 1 的员工,对于每个人,我基本上都会调用 CTE 来让所有员工失望,例如 ManagerId = 2 没有下属,但我需要计算无论如何。有没有一种有效的方法来做到这一点?我正在使用交叉应用将 CTE 置于内联函数中,但我遇到了性能问题。

【问题讨论】:

我不完全理解第二个数据集的要求是什么。您是否要查找每个员工最终向其报告的级别为 0 或 1 的所有员工(包括,在员工为 0 或 1 级别的情况下,员工自己)? 【参考方案1】:

我想我找到了解决方案,我想对此发表意见。

;WITH relation AS 
    (
       SELECT 1 AS ManagerId, 1 as EmployeeId,  0 AS LEVEL UNION    
       SELECT 2 AS ManagerId, 2 as EmployeeId,  0 AS LEVEL UNION
       SELECT 3 AS ManagerId, 3 as EmployeeId,  0 AS LEVEL

       UNION ALL

       SELECT t.[ManagerId], r.EmployeeId, LEVEL + 1 AS LEVEL
         FROM (SELECT EmployeeId, ManagerId FROM #Pepe) r
        INNER JOIN relation T 
           ON r.ManagerId = T.EmployeeId
        WHERE r.ManagerId <> r.EmployeeId 

    )  

SELECT DISTINCT EmployeeId, [ManagerId] FROM relation ORDER BY 2

【讨论】:

【参考方案2】:

你几乎拥有它。只需要从#Pepe 表中选择不同的经理,而不是手动执行 3 条选择语句

DECLARE @Pepe TABLE (EmployeeId INT, ManagerId int)

INSERT INTO @Pepe ( [EmployeeId], [ManagerId] ) VALUES  (1, 1)
INSERT INTO @Pepe ( [EmployeeId], [ManagerId] ) VALUES  (2, 1)
INSERT INTO @Pepe ( [EmployeeId], [ManagerId] ) VALUES  (3, 1)
INSERT INTO @Pepe ( [EmployeeId], [ManagerId] ) VALUES  (4, 3)
INSERT INTO @Pepe ( [EmployeeId], [ManagerId] ) VALUES  (5, 3)
INSERT INTO @Pepe ( [EmployeeId], [ManagerId] ) VALUES  (6, 4)

;WITH relation (ManagerId, EmployeeId, LEVEL)
AS 
(
    SELECT DISTINCT ManagerId, ManagerId AS EmployeeId,  0 AS LEVEL
    FROM @Pepe  

    UNION ALL

    SELECT t.[ManagerId], r.EmployeeId, LEVEL + 1 AS LEVEL
    FROM @Pepe r
      INNER JOIN relation T 
        ON r.ManagerId = T.EmployeeId
    WHERE r.ManagerId <> r.EmployeeId 
)  
SELECT DISTINCT EmployeeId, ManagerId, LEVEL FROM relation ORDER BY ManagerId

【讨论】:

以上是关于如何找到每个经理下的所有员工的主要内容,如果未能解决你的问题,请参考以下文章

如果同一表的另一列中存在值,如何找到对应的列值

递归 CTE - 查找经理下的所有员工

如何限制每个用户 ID 一行

如何使用c#在winforms中为每个用户授予权限

作为产品经理,如何有效应对需求变动和技术开发?

超过经理收入的员工