我正在尝试重建当前使用“RBAR”方法映射组织报告层次结构的存储过程。当组织规模较小时,这种方法运行良好,但随着组织的发展,这种方法并没有很好地扩展。
我想做的是使用递归CTE来帮助加快这个过程。我试过的第一步已经奏效了;映射层次结构中与第一个/顶部节点相关的每个位置。
我的数据与此类似:
POSITION_NBR | REPORTS_TO |
001 001
002 001
003 001
004 002
005 003
006 003
007 004
我目前的做法是:
REPORTS_TO | POSITION_NBR | EMPLEVEL
001 001 0
001 002 1
001 003 1
002 004 2
003 005 2
003 006 2
004 007 3
这是我的SQL:
WITH POSN_HIERARCHY AS
(SELECT POS.REPORTS_TO
,POS.POSITION_NBR
,0 AS EMPLEVEL
FROM dbo.POSITION_BASE POS
WHERE POS.POSITION_NBR = POS.REPORTS_TO
UNION ALL
SELECT POS.REPORTS_TO
,POS.POSITION_NBR
,EMP.EMPLEVEL + 1
FROM dbo.POSITION_BASE POS
INNER JOIN POSN_HIERARCHY EMP
ON EMP.POSITION_NBR = POS.REPORTS_TO
WHERE POS.POSITION_NBR <> POS.REPORTS_TO)
SELECT * FROM POSN_HIERARCHY
我正在努力解决的问题是不仅可以找到与第一个节点相关的层次结构,还可以找到主层次结构中每个层次结构的方法。例如,我当前的SQL将在主要组织的结构中找到我的级别,但我也希望能够在我的经理的层次结构中看到我的级别,以及他的经理的层次结构等。
所以基本上我正在尝试为组织中的每位经理返回一个层次结构。
我的理想输出如下:
REPORTS_TO | POSITION_NBR | EMPLEVEL
001 001 0
001 002 1
001 003 1
001 004 2
001 005 2
001 006 2
001 007 3
002 004 1
002 007 2
003 005 1
003 006 1
004 007 1
因此,输出显示每个人相对于其上方每个父节点的级别。 (007是001的3个级别,002的2个级别,004的1个级别。)
我已经尝试修改锚点查询,以便它返回所有管理器,但这不起作用。我尝试在CTE中查看多个递归,但我也无法使其工作。有人能指出我如何做到这一点的正确方向吗?
答案 0 :(得分:1)
CREATE TABLE #POSITION_BASE(POSITION_NBR VARCHAR(20), REPORTS_TO VARCHAR(20))
INSERT INTO #POSITION_BASE
SELECT '001','001'
UNION ALL
SELECT '002','001'
UNION ALL
SELECT '003','001'
UNION ALL
SELECT '004','002'
UNION ALL
SELECT '005','003'
UNION ALL
SELECT '006','003'
UNION ALL
SELECT '007','004'
我在查询中写了逻辑
;WITH POSN_HIERARCHY AS
(
-- This is your first query in question. There is no changes here.
SELECT POS.REPORTS_TO ,POS.POSITION_NBR ,0 AS EMPLEVEL
FROM #POSITION_BASE POS
WHERE POS.POSITION_NBR = POS.REPORTS_TO
UNION ALL
SELECT POS.REPORTS_TO ,POS.POSITION_NBR ,EMP.EMPLEVEL + 1
FROM #POSITION_BASE POS
INNER JOIN POSN_HIERARCHY EMP
ON EMP.POSITION_NBR = POS.REPORTS_TO
WHERE POS.POSITION_NBR <> POS.REPORTS_TO
)
,CTE2 AS
(
-- There will be no change to top-level parent and the child just below it.
-- We select the children whose primary level is greater than one
SELECT POSITION_NBR,REPORTS_TO,0 EMP
FROM POSN_HIERARCHY
WHERE EMPLEVEL > 1
UNION ALL
-- Finds all the parents for the children whose primary level is greater than one
SELECT CTE.POSITION_NBR ,C.REPORTS_TO ,EMP + 1
FROM CTE2 CTE
INNER JOIN POSN_HIERARCHY C ON C.POSITION_NBR = CTE.REPORTS_TO
WHERE C.POSITION_NBR <> C.REPORTS_TO
)
-- We select the top-level parent and the child just below it
SELECT REPORTS_TO REPORTS_TO,POSITION_NBR,EMPLEVEL
FROM POSN_HIERARCHY
WHERE EMPLEVEL < 2
UNION
-- We select the children whose primary level is greater than one and its parents
-- and increment the number by one to meet our requirement
SELECT REPORTS_TO ,POSITION_NBR,EMP + 1 EMP
FROM CTE2
OPTION(MAXRECURSION 0)
由于SQL FIDDLE有一些内部错误,您可以看到下面的图像结果。
<强> RESULT 强>