您可以添加另一个 CTE 来确定员工人数,然后在 Update 语句中使用它:
WITH OrgChart (employeeID, employeeName,managerID,level)
AS (
SELECT employeeID,employeeName,0 as managerID,0 AS Level
FROM Employees
WHERE managerID IS NULL
UNION ALL
SELECT Employees.employeeID,Employees.employeeName,Employees.managerID,Level + 1
FROM Employees
INNER JOIN OrgChart
ON Employees.managerID = OrgChart.employeeID
)
, SubordinateCount As
(
Select ManagerId, Count(*) As Total
From OrgChart
Group By ManagerId
)
Update Employees
Set TotalOrganization = SubordinateCount.Total
FROM SubordinateCount
Join Employees As E
On E.employeeId = SubordinateCount.ManagerId
添加
规格的变化是您想要计算所有下属员工。诀窍是为员工创建通往每位经理的路径。所以,首先这是我的测试数据:
Insert Employees(EmployeeId, Name, ManagerId) Values(1, 'Alice', Null)
Insert Employees(EmployeeId, Name, ManagerId) Values(2, 'Bob', 1)
Insert Employees(EmployeeId, Name, ManagerId) Values(3, 'Charlie', 1)
Insert Employees(EmployeeId, Name, ManagerId) Values(4, 'Dan', 3)
Insert Employees(EmployeeId, Name, ManagerId) Values(5, 'Ellen', 3)
Insert Employees(EmployeeId, Name, ManagerId) Values(6, 'Fred', 5)
Insert Employees(EmployeeId, Name, ManagerId) Values(7, 'Gale', 6)
Insert Employees(EmployeeId, Name, ManagerId) Values(8, 'Harry', 6)
因此,首先我们编写一个查询,为我们提供通往他们经理的路径:
With
OrgChart As
(
Select E.EmployeeId, E.Name, Null As ManagerId, 0 AS Level
, Cast( '/' + Cast(E.EmployeeId As varchar(10)) + '/' As varchar(100) ) As Path
From dbo.Employees As E
Where E.ManagerId Is Null
Union All
Select E.EmployeeID, E.Name, E.ManagerID, Level + 1
, Cast( OrgChart.Path + Cast(E.EmployeeId As varchar(10)) + '/' As varchar(100))
From dbo.Employees As E
Join OrgChart
On OrgChart.EmployeeId = E.ManagerID
)
Select *
From OrgChart
这会产生:
EmployeeId Name ManagerId Level Path
1 Alice NULL 0 /1/
2 Bob 1 1 /1/2/
3 Charlie 1 1 /1/3/
4 Dan 3 2 /1/3/4/
5 Ellen 3 2 /1/3/5/
6 Fred 5 3 /1/3/5/6/
7 Gale 6 4 /1/3/5/6/7/
8 Harry 6 4 /1/3/5/6/8/
现在我们只需要计算给定员工存在于某人路径中的实例:
With
OrgChart As
(
Select E.EmployeeId, E.Name, Null As ManagerId, 0 AS Level
, Cast( '/' + Cast(E.EmployeeId As varchar(10)) + '/' As varchar(100) ) As Path
From dbo.Employees As E
Where E.ManagerId Is Null
Union All
Select E.EmployeeID, E.Name, E.ManagerID, Level + 1
, Cast( OrgChart.Path + Cast(E.EmployeeId As varchar(10)) + '/' As varchar(100))
From dbo.Employees As E
Join OrgChart
On OrgChart.EmployeeId = E.ManagerID
)
, OrgCounts As
(
Select O.EmployeeId, O.Name, O.ManagerId, O.Level, O.Path
, (Select Count(*)
From OrgChart As O1
Where O1.Path Like '%/' + Cast(E.EmployeeId As varchar(10)) + '/%') - 1 As SubordinateTotal
From Employees As E
Join OrgChart As O
On O.EmployeeId = E.EmployeeId
)
Select O.EmployeeId, O.Name, O.ManagerId, O.Level, O.Path, O.SubordinateTotal
From OrgCounts
我从总数中减去一个以排除当前员工。现在我们已经找到了一个查询来提供正确的结果,我们可以很容易地使用它来进行更新:
With
OrgChart As
(
Select E.EmployeeId, E.Name, Null As ManagerId, 0 AS Level
, Cast( '/' + Cast(E.EmployeeId As varchar(10)) + '/' As varchar(100) ) As Path
From dbo.Employees As E
Where E.ManagerId Is Null
Union All
Select E.EmployeeID, E.Name, E.ManagerID, Level + 1
, Cast( OrgChart.Path + Cast(E.EmployeeId As varchar(10)) + '/' As varchar(100))
From dbo.Employees As E
Join OrgChart
On OrgChart.EmployeeId = E.ManagerID
)
, OrgCounts As
(
Select O.EmployeeId, O.Name, O.ManagerId, O.Level, O.Path
, (Select Count(*)
From OrgChart As O1
Where O1.Path Like '%/' + Cast(E.EmployeeId As varchar(10)) + '/%') - 1 As SubordinateTotal
From Employees As E
Join OrgChart As O
On O.EmployeeId = E.EmployeeId
)
Update Employees
Set TotalOrganization = O.SubordinateTotal
From OrgCounts As O
Join dbo.Employees As E
On E.EmployeeId = O.EmployeeId