查找每个节点的层次结构
Find Hierarchy for each Node
我正在尝试重建当前使用“RBAR”方法来映射我组织的报告层次结构的存储过程。当组织规模较小时,这种方法很管用,但随着组织规模的扩大,这种方法的规模就完全不适用了。
我想做的是使用递归 CTE 来帮助加快进程。我尝试的第一步奏效了;映射层次结构中与 first/top 节点相关的每个位置。
我的数据看起来与此类似:
POSITION_NBR | REPORTS_TO |
001 001
002 001
003 001
004 002
005 003
006 003
007 004
我目前的做法return这个:
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 会在主要组织的结构中找到我的级别,但我也希望能够在我的经理的层次结构中看到我的级别,以及他的经理的层次结构等。
所以基本上我正在尝试 return 组织中每个经理的层次结构。
我理想的输出是这样的:
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级。)
我已经尝试修改锚查询,以便它 return 所有经理,但这没有用。我尝试查看 CTE 中的多个递归,但我也无法使其正常工作。有人可以为我指明正确的方向吗?
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有一些内部错误,您可以看到下面的图像结果。
结果
我正在尝试重建当前使用“RBAR”方法来映射我组织的报告层次结构的存储过程。当组织规模较小时,这种方法很管用,但随着组织规模的扩大,这种方法的规模就完全不适用了。
我想做的是使用递归 CTE 来帮助加快进程。我尝试的第一步奏效了;映射层次结构中与 first/top 节点相关的每个位置。
我的数据看起来与此类似:
POSITION_NBR | REPORTS_TO |
001 001
002 001
003 001
004 002
005 003
006 003
007 004
我目前的做法return这个:
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 会在主要组织的结构中找到我的级别,但我也希望能够在我的经理的层次结构中看到我的级别,以及他的经理的层次结构等。
所以基本上我正在尝试 return 组织中每个经理的层次结构。
我理想的输出是这样的:
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级。)
我已经尝试修改锚查询,以便它 return 所有经理,但这没有用。我尝试查看 CTE 中的多个递归,但我也无法使其正常工作。有人可以为我指明正确的方向吗?
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有一些内部错误,您可以看到下面的图像结果。
结果