我正在尝试根据项目父母的名称生成路径。例如,如果test有父dad路径将是dad/test;如果爸爸有父母gra 的测试路径将是gran /dad/test。
我只有孩子的 id,到目前为止,我只有一个查询,它递归地生成每个人的路径,然后选择正确的路径,但这似乎并不有效。
WITH SubItems
AS (
SELECT CAST([Name] AS VARCHAR(255)) AS [Path],
Id,
ParentId,
0 AS Depth
FROM Items
WHERE Id = 1 -- First parent of everyone
UNION ALL
SELECT CAST(CONCAT(parent.[Path], '/', sub.[Name]) AS VARCHAR(255)),
sub.Id,
sub.ParentId,
parent.Depth + 1
FROM Items sub
JOIN SubItems parent ON parent.Id = sub.ParentId
)
SELECT [Path]
FROM SubItems
WHERE Id = 1425 -- SubItem I want the path of
我也可以向上走,这样会更快,但我无法以这种方式创建路径。我可以尝试连接按“深度”排序的所有结果,但这似乎也不正确。
DECLARE @Path;
WITH ParentItems
AS (
SELECT [Name],
Id,
ParentId,
0 AS Depth
FROM Items
WHERE Id = 1425 -- SubItem I want the path of
UNION ALL
SELECT [Name],
parent.Id,
parent.ParentId,
sub.Depth - 1
FROM Items parent
JOIN ParentItems sub ON sub.ParentId = parent.Id
)
SELECT @Path = COALESCE(@Path + '/', '') + [Name]
FROM ParentItems
ORDER BY Depth;
SELECT @Path;
有没有办法递归向上?
例如,像这样的东西, whereParentPath将CONCAT(ParentPath, '/', [Path])再次等于:
WITH ...
SELECT CONCAT(ParentPath, '/', [Name])
FROM Items
我知道在 C# 中您可以执行以下操作:
function getPath() {
return (parent?.getPath() ?? "") + "/" + this.Name;
}
编辑:为什么我不能构建向上的路径,如下所示:
WITH ParentItems AS (
SELECT i.Name, i.Id, i.ParentId, 0 AS Depth,
CONVERT(VARCHAR(MAX), i.Name) as path
FROM Items i
WHERE i.Id = 1425 -- SubItem I want the path of
UNION ALL
SELECT i.Name, i.Id, i.ParentId, pi.Depth - 1,
CONCAT(pi.Name, '/', i.[Path])
FROM Items i JOIN
ParentItems pi
ON pi.ParentId = parent.Id
)
SELECT *
FROM ParentItems
ORDER BY Depth;
假设上面的例子gra是 parent to dad是 parent to test,这个查询的结果是:
| name | path |
|------|---------------|
| gran | gran/dad/test |
| dad | dad/test |
| test | test |
虽然它应该是相反的:
| name | path |
|------|---------------|
| gran | gran/ |
| dad | gran/dad |
| test | gran/dad/test |
这是因为查询向上传递子名称的方式,将其添加到其父路径而不是相反。