我有一张包含员工详细信息的表
EmpId ManagerId Level Value
1 0 5 CEO
2 1 4 EMP
3 1 4 ORG
4 2 3 NULL
5 2 3 NULL
6 2 2 NULL
7 1 1 NULL
8 5 0 NULL
现在,我必须从员工身份2开始,发现所有人都是低级别的雇员(即2,4,5,6,8)并将其分配给“2”(即EMP)。
预期产出:
EmpId ManagerId Level Value
1 0 5 CEO
2 1 4 EMP
3 1 4 ORG
4 2 3 EMP
5 2 3 EMP
6 2 2 EMP
7 1 1 NULL
8 5 0 EMP
我在尝试什么:
; WITH LevelHire AS
(
SELECT EmpId, ManagerId,Level
FROM EmployeeTable
WHERE EmpId =2
UNION ALL
SELECT Lh.EmpId, RC.ManagerId, Lh.Level
FROM LevelHire LH
INNER JOIN [EmployeeTable] RC
ON LH.EmpId= RC.EmpId
)
SELECT * FROM LevelHire
option (maxrecursion 0)
我怎样才能达到同样的目标?
答案 0 :(得分:2)
你可以尝试这样的事情
;WITH EmployeeTable AS
(
SELECT 1 EmpId,0 ManagerId , 5 Level ,'CEO' Value
UNION ALL SELECT 2,1, 4,'EMP'
UNION ALL SELECT 3,1, 4,'ORG'
UNION ALL SELECT 4,2, 3,NULL
UNION ALL SELECT 5,2, 3,NULL
UNION ALL SELECT 6,2, 2,NULL
UNION ALL SELECT 7,1, 1,NULL
UNION ALL SELECT 8,5, 0,NULL
),LevelHire AS
(
SELECT EmpId, ManagerId,Level,Value
FROM EmployeeTable
WHERE EmpId = 2
UNION ALL
SELECT RC.EmpId, RC.ManagerId, Lh.Level,LH.Value
FROM LevelHire LH
INNER JOIN [EmployeeTable] RC
ON LH.EmpId= RC.ManagerId
)
SELECT E.EmpId, E.ManagerId,E.Level,ISNULL(E.Value ,LH.Value) Value
FROM EmployeeTable E
LEFT JOIN LevelHire LH
ON E.EmpId = LH.EmpId
答案 1 :(得分:1)
了解hierarchyid的时间。首先,一些代码:
IF object_id('tempdb.dbo.#employees') IS NOT NULL
DROP TABLE #employees;
go
WITH Employees AS (
SELECT *
FROM ( VALUES
( 1, NULL, 5, 'CEO'),
( 2, 1, 4, 'EMP'),
( 3, 1, 4, 'ORG'),
( 4, 2, 3, NULL ),
( 5, 2, 3, NULL ),
( 6, 2, 2, NULL ),
( 7, 1, 1, NULL ),
( 8, 5, 0, NULL )
) AS x ( EmpId, ManagerId, Level, Value )
), rcte AS (
SELECT e.EmpId ,
e.ManagerId ,
e.Level ,
e.Value,
CAST('/' + CAST(e.EmpId AS VARCHAR) + '/' AS VARCHAR(MAX)) AS h
FROM Employees AS e
WHERE e.ManagerId IS NULL
UNION ALL
SELECT e.EmpId ,
e.ManagerId ,
e.Level ,
e.Value ,
m.h + CAST(e.EmpId AS VARCHAR) + '/' AS h
FROM Employees AS e
JOIN rcte AS m
ON e.ManagerId = m.EmpId
)
SELECT rcte.EmpId ,
rcte.ManagerId ,
rcte.Level ,
rcte.Value ,
CAST(rcte.h AS HIERARCHYID) AS h
INTO #employees
FROM rcte;
GO
SELECT e.EmpId ,
e.ManagerId ,
e.Level ,
e.Value ,
e.h.ToString() AS h
FROM #employees AS e
JOIN #employees AS m
ON e.h.IsDescendantOf(m.h) = 1
WHERE m.EmpId = 1
SELECT m.EmpId ,
m.ManagerId ,
m.Level ,
m.Value ,
m.h.ToString() AS h
FROM #employees AS e
JOIN #employees AS m
ON e.h.IsDescendantOf(m.h) = 1
WHERE e.EmpId = 8
虽然我需要一个递归的CTE来实际建立层次结构,但是这个人的任何实际查询都会向这个人报告?"和#34;谁报告给这个人?"最终从#employees表中的持久化层次结构中得到满足。最后的两个查询显示了如何在任一方向上遍历层次结构。如果您的层次结构很大(宽,深或两者),这种事情很重要。您需要在组织结构图更改时进行维护,但这是一次性操作。查询数据应该很快,因为谱系与员工记录保持一致。
顺便提一下,您的Level
列对我来说有点奇怪。具体而言,它似乎倒退(即CEO具有最高水平)。我之所以这么说是因为如果/当你在组织结构图中添加另一个级别时,你需要重新调整CEO的每个级别。如果您的首席执行官具有最低级别,那么您只需将该级别降至最低级别,并且不必重新调整任何级别。