编写一个递归 CTE,通过经理获取员工。包括以下列:
- 员工姓氏
- 员工名字
- 部门 ID
- 文件文件夹
- 经理姓氏
- 经理名字
名为FileFolder
的列用于存储每个员工的绩效评估。请注意,由于经理还可以访问直接或间接向他们报告的所有人员,因此每个经理的文件夹最终将设置为不仅包含他们自己的绩效审核文件,还包含直接报告的每个员工的所有子文件夹给他们。为了帮助实现这一点,还包括一个名为“文件路径”的列,该列将确定并显示每个员工的文件路径名,在子文件夹之间使用 Windows 样式的\,即。格式为 ManagerFileFolder\EmployeeFileFolder\
等
为了说明这是如何工作的,例如,如果我直接向 Dev Sainani 报告,而 Dev 向 Peter Devlin 报告,那么我的文件路径将是 PeterDevlin\DevSainani\OsamAl
我不确定如何在不更改表的情况下包含不在我提供的数据库表中的列,以及如何合并上面提到的“文件路径”要求。
这是 Employees
表(我提供的唯一表)的脚本:
CREATE TABLE dbo.Employees
(
EmployeeID INT IDENTITY PRIMARY KEY,
DepartmentID INT
CONSTRAINT FK_Employee_Department
FOREIGN KEY REFERENCES dbo.Departments (DepartmentID),
ManagerEmployeeID INT
CONSTRAINT FK_Employee_Manager
FOREIGN KEY REFERENCES dbo.Employees (EmployeeID),
FirstName NVARCHAR(60),
LastName NVARCHAR(60),
Salary MONEY
CONSTRAINT CK_EmployeeSalary CHECK (Salary >= 0),
CommissionBonus MONEY
CONSTRAINT CK_EmployeeCommission CHECK (CommissionBonus >= 0),
FileFolder NVARCHAR(256)
CONSTRAINT DF_FileFolder DEFAULT 'ToBeCreated'
);
这就是我所做的,我知道它不正确,因为当我为此 CTE 编写 SELECT
语句时,我没有得到表中显示的任何数据:
WITH GetEmployeeByManager AS
(
SELECT
FirstName, LastName, DepartmentID, FileFolder
FROM
dbo.Employees
WHERE
ManagerEmployeeID IS NULL
UNION ALL
SELECT
e.LastName, e.FirstName, e.DepartmentID, e.FileFolder
FROM
Employees e
JOIN
GetEmployeeByManager ge ON e.ManagerEmployeeID = ge.ManagerEmployeeID
)
SELECT *
FROM GetEmployeeByManager ge
JOIN dbo.Employees e ON ge.ManagerEmployeeID = e.ManagerEmployeeID;
最佳答案
此脚本将为您提供您所描述的所需输出。在 CREATE
表语句中,为了简单起见,我删除了外键约束,因为我使用 SQL Fiddle 构建此查询。
MS SQL Server 2017 架构设置:
CREATE TABLE Employees
(
EmployeeID INT not null PRIMARY KEY,
DepartmentID INT not null,
ManagerEmployeeID INT null,
FirstName NVARCHAR(60),
LastName NVARCHAR(60),
Salary MONEY
CONSTRAINT CK_EmployeeSalary CHECK (Salary >= 0),
CommissionBonus MONEY
CONSTRAINT CK_EmployeeCommission CHECK (CommissionBonus >= 0),
FileFolder NVARCHAR(256)
CONSTRAINT DF_FileFolder DEFAULT 'ToBeCreated'
);
INSERT INTO Employees (EmployeeID, DepartmentID, ManagerEmployeeID, FirstName, LastName, Salary, CommissionBonus, FileFolder)
VALUES (1, 101, null, 'Ted', 'Smith', 12000.00, 120.00, 'TedSmith')
, (2, 101, 1, 'John','Doe', 10000.00, 100.00, 'JohnDoe')
, (3, 101, 2, 'Dev', 'Patel', 8000.00, 80.00, 'DevPatel')
;
查询 1:
WITH GetEmployeeByManager AS
(
SELECT
e.EmployeeID
, e.FirstName
, e.LastName
, e.DepartmentID
, e.ManagerEmployeeID
, em.FirstName as ManagerFirstName
, em.LastName as ManagerLastName
, e.FileFolder
, e.FileFolder as FilePath
, 0 as hierarchy_level
FROM Employees as e
LEFT OUTER JOIN Employees as em
ON em.EmployeeID = e.ManagerEmployeeID
WHERE e.ManagerEmployeeID is null --First query gets only managers
UNION ALL
SELECT
e.EmployeeID
, e.FirstName
, e.LastName
, e.DepartmentID
, e.ManagerEmployeeID
, em.FirstName as ManagerFirstName
, em.LastName as ManagerLastName
, e.FileFolder
, CAST(em.FilePath + '/' + e.FileFolder as nvarchar(256)) as FileFolder
, em.hierarchy_level + 1 as hierarchy_level
FROM Employees e
INNER JOIN GetEmployeeByManager as em
ON em.EmployeeID = e.ManagerEmployeeID
WHERE em.hierarchy_level < 50
)
SELECT *
FROM GetEmployeeByManager ge
<强> Results :
| EmployeeID | FirstName | LastName | DepartmentID | ManagerEmployeeID | ManagerFirstName | ManagerLastName | FileFolder | FilePath | hierarchy_level |
|------------|-----------|----------|--------------|-------------------|------------------|-----------------|------------|---------------------------|-----------------|
| 1 | Ted | Smith | 101 | (null) | (null) | (null) | TedSmith | TedSmith | 0 |
| 2 | John | Doe | 101 | 1 | Ted | Smith | JohnDoe | TedSmith/JohnDoe | 1 |
| 3 | Dev | Patel | 101 | 2 | John | Doe | DevPatel | TedSmith/JohnDoe/DevPatel | 2 |
关于sql - 递归 CTE 通过经理获取员工,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74426304/