我希望获得每个部门的路径,格式为1.1,1.2等。 这是我的部门表:
id name parentId
--------------------
1 Dep 1 0
2 Dep 2 1
3 Dep 3 0
4 Dep 4 1
5 Dep 5 4
6 Dep 6 2
这是我的递归CTE,从根部开始给我父母和孩子一张平台。
WITH recursiveCte (parentId, id, name, Level)
AS
(
-- Anchor member definition
SELECT
d.parentId, d.id, d.name,
0 AS Level
FROM
Department AS d
WHERE
parentId = 0
UNION ALL
-- Recursive member definition
SELECT
d.parentId, d.id, d.name,
Level + 1
FROM
Department AS d
INNER JOIN
recursiveCte AS r ON d.parentId = r.id
)
-- Statement that executes the CTE
SELECT parentId,id, name, Level
FROM recursiveCte
ORDER BY id
目前的结果:
parentId id name Level
-------------------------------
0 1 Dep 1 0
1 2 Dep 2 1
0 3 Dep 3 0
1 4 Dep 4 1
4 5 Dep 5 2
2 6 Dep 6 2
期望的结果:
parentId id name Level Path
--------------------------------------
0 1 Dep 1 0 1
1 2 Dep 2 1 1.1
2 6 Dep 6 2 1.1.1
1 4 Dep 4 1 1.2
4 5 Dep 5 2 1.2.1
0 3 Dep 3 0 2
感谢。
答案 0 :(得分:1)
这是一个有效的解决方案。很难用文字描述为什么这样有效,所以我建议拆开查询,看看它是如何工作的。基本上,我们递归地构建您想要查看的路径字符串,使用ROW_NUMBER
跟踪每个新路径添加所属的特定父级。
recursiveCte (parentId, id, name, Level, Path, FullPath) AS (
SELECT d.parentId, d.id, d.name, 0 AS Level,
CAST(ROW_NUMBER() OVER (ORDER BY d.id) AS nvarchar(max)),
RIGHT('000' + CAST(ROW_NUMBER() OVER (ORDER BY d.id) AS nvarchar(max)), 3)
FROM Department AS d
WHERE parentId = 0
UNION ALL
SELECT d.parentId, d.id, d.name, r.Level + 1,
r.Path + '.' +
CAST(ROW_NUMBER() OVER (PARTITION BY r.Level ORDER BY d.id) AS nvarchar(max)),
r.FullPath + '.' + RIGHT('000' + CAST(ROW_NUMBER() OVER
(PARTITION BY r.Level ORDER BY d.id) AS nvarchar(max)), 3)
FROM Department AS d
INNER JOIN recursiveCte AS r
ON d.parentId = r.id
)
SELECT parentId, id, name, Level, Path, FullPath
FROM recursiveCte
ORDER BY FullPath;
修改强>
我稍微编辑了我的原始答案,以便它现在使用固定宽度版本对路径字符串进行排序,即每个数字的固定宽度为3位数。这意味着001
将始终在010
之前排序,这是我们想要的行为。