EmployeeId、ManagerId、およびNameフィールドを持つEmployeeテーブルがあります。
目標は、従業員からトップマネージャーにすべての行をフェッチして再帰的にすることです(ManagerIdはnull)。
私はこのリンクを見つけました これはコードのベースを取得するのに役立ちましたが、私の場合にはうまくいきません
DECLARE @EmployeeTable table ([EmployeeId] int, [name] varchar(10), [managerId] int)
INSERT @EmployeeTable VALUES (1,'Jerome', NULL ) -- tree is as follows:
INSERT @EmployeeTable VALUES (2,'Joe' ,1) -- 1-Jerome
INSERT @EmployeeTable VALUES (3,'Paul' ,2) -- / \
INSERT @EmployeeTable VALUES (4,'Jack' ,3) -- 2-Joe 9-Bill
INSERT @EmployeeTable VALUES (5,'Daniel',3) -- / \ \
INSERT @EmployeeTable VALUES (6,'David' ,2) -- 3-Paul 6-David 10-Sam
INSERT @EmployeeTable VALUES (7,'Ian' ,6) -- / \ / \
INSERT @EmployeeTable VALUES (8,'Helen' ,6) -- 4-Jack 5-Daniel 7-Ian 8-Helen
INSERT @EmployeeTable VALUES (9,'Bill ' ,1) --
INSERT @EmployeeTable VALUES (10,'Sam' ,9) --
DECLARE @employeeId int = 3
;WITH StaffTree AS
(
SELECT
c.[EmployeeId], c.[name], c.managerId, 0 AS [Level]
FROM @EmployeeTable c
LEFT OUTER JOIN @EmployeeTable cc ON c.managerId=cc.EmployeeId
WHERE c.EmployeeId=@employeeId OR (@employeeId IS NULL AND c.managerId IS NULL)
UNION ALL
SELECT
s.[EmployeeId], s.[name], s.managerId, t.[Level]+1
FROM StaffTree t
INNER JOIN @EmployeeTable s ON t.[EmployeeId]=s.managerId
WHERE s.managerId=@employeeId OR @employeeId IS NULL OR t.Level>1
)
SELECT * FROM StaffTree
従業員3の階層を選択した場合、結果は次のようになります。
EmployeeId | Name | ManagerId
1 | Jerome | NULL
2 | Joe | 1
3 | Paul | 2
再帰部分の内部結合の列を交換することは、これを回避する方法です。
結合列がt.[EmployeeId]=s.managerId
からs.[EmployeeId]=t.managerId
に変更されました
必要と思われない部分を削除しました。
DECLARE @employeeId int = 3
;WITH StaffTree AS
(
SELECT
c.[EmployeeId], c.[name], c.managerId, 0 AS [Level]
FROM @EmployeeTable c
WHERE c.EmployeeId=@employeeId OR (@employeeId IS NULL AND c.managerId IS NULL)
UNION ALL
SELECT
s.[EmployeeId], s.[name], s.managerId, t.[Level]+1
FROM StaffTree t
INNER JOIN @EmployeeTable s ON s.[EmployeeId]=t.managerId
)
SELECT EmployeeId,
name,
managerId
FROM StaffTree
ORDER BY managerId asc;
結果
EmployeeId name managerId
1 Jerome NULL
2 Joe 1
3 Paul 2
リンクした例をコピーするときに小さなエラーが発生したようです-
c.[EmployeeId], c.[name], c.managerId, 0 AS [Level]
する必要があります
c.[EmployeeId], c.[name], c.managerId, 1 AS [Level]
変更を加えると、コードは例と同じように機能します。
このリンクは、優れた有用な例で再帰CTEを学習するのに役立ちます。 https://www.codeproject.com/Articles/818694/SQL-queries-to-manage-hierarchical-or-parent-child 。