如何获得在主管下工作的各级员工名单?

How to get list of all levels of employees working under supervisor?

我需要将员工列表缩小到在特定主管或主管或经理手下工作的最低级别。

下面是员工的等级制度,每个员工都有一个主管,主管向主管报告,主管向经理报告如下:

table中的数据只有如下2个字段:

我的 SQL 查询是 SELECT Employee_ID FROM DATABASE_TABLE WHERE Supervisor_ID='Joe'。结果是我得到了向 Joe 报告的所有员工的最低级别列表。同样,如果我查询 Supervisor_ID='David',我应该让所有向 David 报告的员工的最低级别。

我在 Oracle 中有使用 CONNECT_BY_PATH 进行此类查询的经验,但我不知道如何在 MS SQL 中实现这一点。一个例子将是非常可观的。谢谢。

Create Table and Insert Statements:

CREATE TABLE DATABASE_TABLE(Employee_ID varchar(255),Supervisor_ID varchar(255));

INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Alice','Dave');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Olive','Dave');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Barton','Dave');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Almira','Jacob');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Charles','Jacob');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Davis','Jacob');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Robert','Risha');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Peter','Risha');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Ethel','Risha');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Isaac','Jospeh');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Sophia','Jospeh');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Rosa','Jospeh');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Joshua','Dandy');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Silas','Dandy');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Fred','Dandy');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Frank','Andrew');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Howard','Andrew');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Ralph','Andrew');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Dennis','Henry');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Alex','Henry');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Floyd','Henry');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Carlos','Nelson');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Homer','Nelson');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Harold','Nelson');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Leo','Simon');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Warren','Simon');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Clifford','Simon');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Martha','Casper');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Hazel','Casper');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Irene','Casper');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Dave','Betsy');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Jacob','Betsy');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Risha','David');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Jospeh','David');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Dandy','Phillip');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Andrew','Phillip');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Henry','Harvey');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Nelson','Harvey');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Simon','Paul');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Casper','Paul');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Betsy','Joe');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('David','Joe');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Phillip','Joe');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Harvey','Joe');
INSERT INTO DATABASE_TABLE(Employee_ID, Supervisor_ID) VALUES ('Paul','Joe');

这里有一个示例,可以让您了解递归 CTE 的用途。

示例数据:

CREATE TABLE DATABASE_TABLE 
(
  Employee_Name nvarchar(255) PRIMARY KEY,
  Supervisor_Name nvarchar(255) NOT NULL
);

CREATE INDEX [ix_database_table_supervisor]
    ON DATABASE_TABLE (Supervisor_Name);
GO

INSERT INTO DATABASE_TABLE
(Employee_Name, Supervisor_Name) VALUES 
  ('Alice','Dave')
, ('Olive','Dave')
, ('Barton','Dave')
, ('Almira','Jacob')
, ('Charles','Jacob')
, ('Davis','Jacob')
, ('Robert','Risha')
, ('Peter','Risha')
, ('Ethel','Risha')
, ('Isaac','Jospeh')
, ('Sophia','Jospeh')
, ('Rosa','Jospeh')
, ('Joshua','Dandy')
, ('Silas','Dandy')
, ('Fred','Dandy')
, ('Frank','Andrew')
, ('Howard','Andrew')
, ('Ralph','Andrew')
, ('Dennis','Henry')
, ('Alex','Henry')
, ('Floyd','Henry')
, ('Carlos','Nelson')
, ('Homer','Nelson')
, ('Harold','Nelson')
, ('Leo','Simon')
, ('Warren','Simon')
, ('Clifford','Simon')
, ('Martha','Casper')
, ('Hazel','Casper')
, ('Irene','Casper')
, ('Dave','Betsy')
, ('Jacob','Betsy')
, ('Risha','David')
, ('Jospeh','David')
, ('Dandy','Phillip')
, ('Andrew','Phillip')
, ('Henry','Harvey')
, ('Nelson','Harvey')
, ('Simon','Paul')
, ('Casper','Paul')
, ('Betsy','Joe')
, ('David','Joe')
, ('Phillip','Joe')
, ('Harvey','Joe')
, ('Paul','Joe')

查询:

DECLARE @HeadName nvarchar(255);
SET @HeadName = 'David';

DECLARE @MaxLvl INT = 2;


WITH RCTE_DATA AS
(
   -- seeding the recursion
   SELECT
   t.Employee_Name AS Head_Name,
   t.Supervisor_Name AS Manager_Name,
   0 AS Lvl,
   t.Employee_Name, 
   t.Supervisor_Name
   FROM DATABASE_TABLE t
   WHERE t.Employee_Name = @HeadName

   UNION ALL

   -- looping the recursion  
   SELECT 
   c.Head_Name,
   c.Manager_Name,
   c.Lvl + 1,
   t.Employee_Name, 
   t.Supervisor_Name
   FROM RCTE_DATA c
   JOIN DATABASE_TABLE t
     ON t.Supervisor_Name = c.Employee_Name
   WHERE c.Lvl < @MaxLvl
)
SELECT 
Employee_Name, 
Supervisor_Name, 
Head_Name,
Manager_Name
FROM RCTE_DATA
WHERE Lvl = @MaxLvl

结果:

Employee_Name | Supervisor_Name | Head_Name | Manager_Name
:------------ | :-------------- | :-------- | :-----------
Ethel         | Risha           | David     | Joe         
Peter         | Risha           | David     | Joe         
Robert        | Risha           | David     | Joe         
Isaac         | Jospeh          | David     | Joe         
Rosa          | Jospeh          | David     | Joe         
Sophia        | Jospeh          | David     | Joe         

db<>fiddle here

select * from  (

SELECT a.Employee_Name, a.Supervisor_Name, b.Supervisor_Name as Head_Name,  c.Supervisor_Name as Manager_Name
FROM DATABASE_TABLE a
LEFT JOIN DATABASE_TABLE b ON a.Supervisor_Name = b.Employee_Name
LEFT JOIN DATABASE_TABLE c ON b.Supervisor_Name = c.Employee_Name) as t

where t.Head_Name='David'
order by Supervisor_Name ;