我有一个包含2列的表[部门]:
[ IdDepartment
[ IdSubDepartment
该表是一种层次结构:
IdDepartment | IdSubDepartment
1 | 2
1 | 3
2 | 4
3 | 5
如果我搜索部门 5 ,我想获得以下5 - > 3 - > 1 (我每次只需要X级 - 并不总是根)。
我编写了一个获取部门ID并返回其第3级的查询(比如我输入ID 5并返回1)。它工作得很快,很好。问题是当我为7K部门做这件事时,它会被卡住。
我想将表格转换为这样的支点:
IdDepartment0 | IdDepartment1 | IdDepartment2 ...
1 2 4
1 3 5
重要:我知道每个部门的级别。 所以,当我得到第5部门时,我知道它在第2级(IdDepartment2) 所以我可以立即查询我的新表并获得我想要的每个部门级别。
如何转换为新表?
提前谢谢 叶兰答案 0 :(得分:0)
此剪辑可以扩展为包括更深的嵌套。
它可能会被优化一些。
;WITH cteLvl AS
(
SELECT IdDepartment, IdSubDepartment, 0 AS Lvl
FROM Department
WHERE IdDepartment NOT IN (SELECT IdSubDepartment FROM Department WHERE IdSubDepartment IS NOT NULL)
UNION ALL
SELECT B.IdDepartment, B.IdSubDepartment, A.Lvl + 1
FROM cteLvl A
INNER JOIN Department B ON B.IdDepartment = A.IdSubDepartment
)
, cteLeaf AS
(
SELECT *, ROW_NUMBER() OVER(ORDER BY IdDepartment) AS GroupId
FROM Department
WHERE IdSubDepartment IS NULL
UNION ALL
SELECT B.IdDepartment, B.IdSubDepartment, A.GroupId
FROM cteLeaf A
INNER JOIN Department B ON A.IdDepartment = B.IdSubDepartment
)
, cteCombined AS
(
SELECT A.IdDepartment, A.GroupId, B.Lvl FROM cteLeaf A
INNER JOIN (SELECT DISTINCT IdDepartment, Lvl FROM cteLvl) B ON A.IdDepartment = B.IdDepartment
)
--SELECT * FROM cteCombined
SELECT GroupId, [0] AS Dep0, [1] AS Dep1, [2] AS Dep2, [3] AS Dep3, [4] AS Dep4
FROM
(SELECT GroupId, Lvl, IdDepartment
FROM cteCombined) P
PIVOT
(
SUM(IdDepartment)
FOR Lvl IN
( [0], [1], [2], [3], [4] )
) AS V
不使用PIVOT结构的效果相同:
SELECT
GroupId,
MAX(CASE Lvl WHEN 0 THEN IdDepartment END) AS Dep0,
MAX(CASE Lvl WHEN 1 THEN IdDepartment END) AS Dep1,
MAX(CASE Lvl WHEN 2 THEN IdDepartment END) AS Dep2,
MAX(CASE Lvl WHEN 3 THEN IdDepartment END) AS Dep3
FROM cteCombined
GROUP BY GroupId