我有一个Employee IDs
表和相应的Manager IDs
,如下所示:
所需结果:高级经理专栏。该专栏的汇总经理可以直接向约翰·史密斯(EmpID: 1
)或安娜·怀特(EmpID: 2
)汇报。
示例:汤姆向杰克报告,蒂姆向安娜报告。
因此,杰克·布莱克的高级经理是蒂姆·史密斯(4
。
汤姆->杰克-> 蒂姆->安娜
我已经处理过CTE
,但是查询返回了很多重复的行。否则,CTE
输出正确的数据。
WITH cte AS
(
SELECT EmpID, FirstName, LastName, EmpID as SeniorManager
FROM Employees
WHERE ManagerID < 3
AND EmpActive = 1
UNION ALL
SELECT emp.EmpID, emp.FirstName, emp.LastName, c.SeniorManager
FROM Employees emp
JOIN cte c ON c.EmpID = emp.ManagerID
WHERE emp.EmpID <> emp.ManagerID
AND emp.EmpActive = 1
)
SELECT * FROM cte
示例数据是实际数据的过分简化的版本-位于公司数据库中。我的主要问题:为什么CTE会返回重复的行?
以下是示例数据:
CREATE TABLE Employees (
EmpID INT NOT NULL PRIMARY KEY,
FirstName VARCHAR(35) NOT NULL,
LastName VARCHAR(35) NOT NULL,
ManagerID INT NOT NULL);
INSERT INTO Employees
(EmpID, FirstName, LastName, ManagerID)
VALUES
(1, 'John', 'Smith', 2),
(2, 'Anna', 'White', 1),
(3, 'Jack', 'Black', 4),
(4, 'Tim', 'Smith', 2),
(5, 'Jason', 'Black', 3),
(6, 'Tom', 'Black', 3);
答案 0 :(得分:1)
您可以尝试添加level
列来表示人员层次结构。
那时只有level = 1
个人。
WITH cte AS
(
SELECT EmpID,FirstName,LastName,ManagerID,1 level
FROM Employees
UNION ALL
SELECT t2.EmpID,t2.FirstName,t2.LastName,t2.ManagerID,level+ 1
FROM cte t1 JOIN Employees t2
on t1.EmpId = t2.ManagerID
WHERE t1.ManagerID <> t2.EmpId
)
SELECT EmpID,FirstName,LastName
FROM cte t1
where not exists (
select 1
from cte tt
WHERE tt.level = 2 and t1.EmpID = tt.EmpID
) and level = 1
结果
mpID FirstName LastName
1 John Smith
2 Anna White
答案 1 :(得分:-2)
经过大量的故障排除后,我找到了解决方案。希望这会帮助需要帮助的人:)
WITH cte AS
(
SELECT EmpID, FirstName, LastName, EmpID as SeniorManager
FROM Employees
WHERE ManagerID <= 2
AND Active = 1
UNION ALL
SELECT e.EmpID, e.FirstName, e.LastName, c.SeniorManager
FROM tblEmployee e
JOIN cte c ON c.EmpID = e.ManagerID
WHERE e.EmpID <> e.ManagerID
AND e.EmpID >= 3
AND e.Active = 1
)
SELECT EmpID, FirstName, LastName, MAX(SeniorManager) SeniorManager FROM cte
GROUP BY EmpID, FirstName, LastName
说明:
在连接的第二部分中添加了e.EmpID> 3。重复的行是由于无限循环造成的,因为有2个人互相作为管理员,所以我不得不将它们排除在外。
为每个重复的EmpID
选择最后一行。由于某种原因,CTE每个EmpID
都有2条记录,第一条记录包含top-level manager
,第二行包含second-level manager
。因此,我需要选择第二行。
编辑:
我的OP声明该代码已经给了我想要的输出,除了它陷入无限循环。那是我的主要问题,在排除了第一批雇员之后,问题得到解决。
我正在处理公司数据,该公司数据比显示的示例数据复杂得多,我无法在此处复制它或修复数据。如果有人遇到类似的问题,我不知道是否能为您提供确切的解决方案,但希望我提供的代码足以入门。
为什么我回答了自己的问题却接受了别人的回答:我的回答非常特定于数据库。它已经解决了这个特定问题,但我认为这不是最好的方法。我接受的答案更好。