使用 CTE 的递归查询需要 help/advise
Required help/advise on Recursive Queries Using CTE
我正在尝试从递归查询结果中获取 DepartmentCode
类似于 Lvl
列的重复员工(经理 - 主管 - CEO 具有完整的层次结构)。
找到几个现有的问答,但这些似乎不适合我的情况。目的是当结果数据用任何 DepartmentCode
过滤时,具有完整的层次结构,直到根节点 (CEO)。当我尝试使用以下递归 CTE 时,Lvl
列看起来很完美,即当数据过滤 Lvl
列的任何 ID 时,它会得到员工、经理、董事和首席执行官(完整的层次结构链)。
我想知道是否可以使用 Recursive CTE 或其他方法对 DepartmentCode
列应用相同的方法。任何建议将不胜感激!
我试过的查询,result is here..(我对结果中出现的重复值没意见)
WITH CTE AS
(
SELECT E.EmployeeID, E.EmpName, E.Title, DepartmentCode, ' ' DepartTest, E.ManagerID, 1 as Lvl
FROM MyEmployees AS E
UNION ALL
SELECT E.EmployeeID, E.EmpName, E.Title, E.DepartmentCode, E.DepartmentCode, E.ManagerID, Lvl + 1
FROM MyEmployees AS E
JOIN CTE ON E.EmployeeID = CTE.ManagerID
--E.ManagerID = CTE.EmployeeID
)
SELECT * FROM CTE
Order by Lvl
go
示例数据脚本:
CREATE TABLE dbo.MyEmployees
(
EmployeeID smallint NOT NULL,
EmpName nvarchar(30) NOT NULL,
Title nvarchar(50) NOT NULL,
DepartmentCode varchar(3),
ManagerID int NULL,
CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC)
);
-- Populate the table with values.
INSERT INTO dbo.MyEmployees
(EmployeeID, EmpName, Title, DepartmentCode, ManagerID)
VALUES
(1, N'Ken', N'Chief Executive Officer', 'SMG', NULL)
,(201, N'Brian', N'Director', 'OPD',1)
,(301, N'Stephen', N'IT Manager', 'ICT',201)
,(302, N'Michael', N'IT Position1','ICT',301)
,(303, N'Linda', N'IT Position2','ICT', 301)
,(401, N'Syed', N'Procurement Position1','PRO',201)
,(402, N'Abbas', N'Procurement Position1','PRO',401)
,(403, N'Lynn', N'Procurement Position2','PRO',401)
GO
此代码更改可能对您有所帮助
;WITH CTE
AS
(
SELECT
EmployeeID
,EmpName
,ManagerID
,CAST('\'+EmpName AS VARCHAR(100)) AS ManagerName
,1 as Lvl
FROM MyEmployees
WHERE managerid IS NULL
union all
SELECT
e.EmployeeID
,e.EmpName
, e.ManagerID
,CAST(ManagerName+'\'+c.EmpName AS VARCHAR(100)) AS ManagerName
, Lvl+1
FROM CTE c
INNER JOIN MyEmployees e
ON c.EmployeeID = e.ManagerID
)
SELECT EmployeeID,
EmpName,
ManagerID,
RIGHT(ManagerName,LEN(ManagerName)-1) AS ManagerName,
Lvl
FROM CTE
GO
结果
EmployeeID EmpName ManagerID ManagerName Lvl
*****************************************************************
1 Ken NULL Ken 1
201 Brian 1 Ken\Ken 2
301 Stephen 201 Ken\Ken\Brian 3
401 Syed 201 Ken\Ken\Brian 3
402 Abbas 401 Ken\Ken\Brian\Syed 4
403 Lynn 401 Ken\Ken\Brian\Syed 4
302 Michael 301 Ken\Ken\Brian\Stephen 4
303 Linda 301 Ken\Ken\Brian\Stephen 4
调整后的查询(根据评论):
;WITH CTE
AS
(
SELECT
EmployeeID
,Title
,ManagerID
,DepartmentCode
,1 as Lvl
FROM MyEmployees
--WHERE managerid IS NULL
union all
SELECT
e.EmployeeID
,e.Title
,e.ManagerID
,c.DepartmentCode
, Lvl+1
FROM CTE c
INNER JOIN MyEmployees e
ON c.ManagerID = e.EmployeeID
)
SELECT EmployeeID,
Title,
ManagerID,
DepartmentCode,
--RIGHT(ManagerName,LEN(ManagerName)-1) AS ConcatManagerName,
Lvl
FROM CTE
Order by DepartmentCode
我正在尝试从递归查询结果中获取 DepartmentCode
类似于 Lvl
列的重复员工(经理 - 主管 - CEO 具有完整的层次结构)。
找到几个现有的问答,但这些似乎不适合我的情况。目的是当结果数据用任何 DepartmentCode
过滤时,具有完整的层次结构,直到根节点 (CEO)。当我尝试使用以下递归 CTE 时,Lvl
列看起来很完美,即当数据过滤 Lvl
列的任何 ID 时,它会得到员工、经理、董事和首席执行官(完整的层次结构链)。
我想知道是否可以使用 Recursive CTE 或其他方法对 DepartmentCode
列应用相同的方法。任何建议将不胜感激!
我试过的查询,result is here..(我对结果中出现的重复值没意见)
WITH CTE AS
(
SELECT E.EmployeeID, E.EmpName, E.Title, DepartmentCode, ' ' DepartTest, E.ManagerID, 1 as Lvl
FROM MyEmployees AS E
UNION ALL
SELECT E.EmployeeID, E.EmpName, E.Title, E.DepartmentCode, E.DepartmentCode, E.ManagerID, Lvl + 1
FROM MyEmployees AS E
JOIN CTE ON E.EmployeeID = CTE.ManagerID
--E.ManagerID = CTE.EmployeeID
)
SELECT * FROM CTE
Order by Lvl
go
示例数据脚本:
CREATE TABLE dbo.MyEmployees
(
EmployeeID smallint NOT NULL,
EmpName nvarchar(30) NOT NULL,
Title nvarchar(50) NOT NULL,
DepartmentCode varchar(3),
ManagerID int NULL,
CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC)
);
-- Populate the table with values.
INSERT INTO dbo.MyEmployees
(EmployeeID, EmpName, Title, DepartmentCode, ManagerID)
VALUES
(1, N'Ken', N'Chief Executive Officer', 'SMG', NULL)
,(201, N'Brian', N'Director', 'OPD',1)
,(301, N'Stephen', N'IT Manager', 'ICT',201)
,(302, N'Michael', N'IT Position1','ICT',301)
,(303, N'Linda', N'IT Position2','ICT', 301)
,(401, N'Syed', N'Procurement Position1','PRO',201)
,(402, N'Abbas', N'Procurement Position1','PRO',401)
,(403, N'Lynn', N'Procurement Position2','PRO',401)
GO
此代码更改可能对您有所帮助
;WITH CTE
AS
(
SELECT
EmployeeID
,EmpName
,ManagerID
,CAST('\'+EmpName AS VARCHAR(100)) AS ManagerName
,1 as Lvl
FROM MyEmployees
WHERE managerid IS NULL
union all
SELECT
e.EmployeeID
,e.EmpName
, e.ManagerID
,CAST(ManagerName+'\'+c.EmpName AS VARCHAR(100)) AS ManagerName
, Lvl+1
FROM CTE c
INNER JOIN MyEmployees e
ON c.EmployeeID = e.ManagerID
)
SELECT EmployeeID,
EmpName,
ManagerID,
RIGHT(ManagerName,LEN(ManagerName)-1) AS ManagerName,
Lvl
FROM CTE
GO
结果
EmployeeID EmpName ManagerID ManagerName Lvl
*****************************************************************
1 Ken NULL Ken 1
201 Brian 1 Ken\Ken 2
301 Stephen 201 Ken\Ken\Brian 3
401 Syed 201 Ken\Ken\Brian 3
402 Abbas 401 Ken\Ken\Brian\Syed 4
403 Lynn 401 Ken\Ken\Brian\Syed 4
302 Michael 301 Ken\Ken\Brian\Stephen 4
303 Linda 301 Ken\Ken\Brian\Stephen 4
调整后的查询(根据评论):
;WITH CTE
AS
(
SELECT
EmployeeID
,Title
,ManagerID
,DepartmentCode
,1 as Lvl
FROM MyEmployees
--WHERE managerid IS NULL
union all
SELECT
e.EmployeeID
,e.Title
,e.ManagerID
,c.DepartmentCode
, Lvl+1
FROM CTE c
INNER JOIN MyEmployees e
ON c.ManagerID = e.EmployeeID
)
SELECT EmployeeID,
Title,
ManagerID,
DepartmentCode,
--RIGHT(ManagerName,LEN(ManagerName)-1) AS ConcatManagerName,
Lvl
FROM CTE
Order by DepartmentCode