別の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
現在の従業員を除外するために、合計から1を引きます。適切な結果を提供するクエリが見つかったので、それを使用して更新を簡単に行うことができます。
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