You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何获取树形路径结果集?附数据表结构与预期结果

如何生成树形结构的层级路径(如Master/Employee/Leave)?

先明确你的需求:

原始数据表

IDNameParentID
1Master0
2Employee1
3Leave2
4Admin1

期望生成带层级路径的结果

IDNameParentIDResult
1Master0Master
2Employee1Master/Employee
3Leave2Master/Employee/Leave
4Admin1Master/Admin

这是很常见的树形结构遍历需求,核心是通过递归查询拼接父节点到当前节点的名称,下面分不同数据库给出实现方案:

方案1:SQL Server / PostgreSQL(支持递归CTE)

递归CTE是最简洁高效的方式,直接遍历树形结构拼接路径:

WITH RecursiveCTE AS (
    -- 锚点:先取出所有根节点(ParentID=0)
    SELECT 
        ID, 
        Name, 
        ParentID, 
        CAST(Name AS VARCHAR(MAX)) AS Result
    FROM YourTableName
    WHERE ParentID = 0

    UNION ALL

    -- 递归:关联父节点,把当前节点名称拼接到父路径后面
    SELECT 
        t.ID, 
        t.Name, 
        t.ParentID, 
        CAST(r.Result + '/' + t.Name AS VARCHAR(MAX)) AS Result
    FROM YourTableName t
    INNER JOIN RecursiveCTE r ON t.ParentID = r.ID
)
SELECT * FROM RecursiveCTE
ORDER BY ID;

方案2:MySQL 8.0+(支持递归CTE)

MySQL 8.0及以后版本也支持递归CTE,语法和上面类似:

WITH RECURSIVE RecursiveCTE AS (
    SELECT 
        ID, 
        Name, 
        ParentID, 
        Name AS Result
    FROM YourTableName
    WHERE ParentID = 0

    UNION ALL

    SELECT 
        t.ID, 
        t.Name, 
        t.ParentID, 
        CONCAT(r.Result, '/', t.Name) AS Result
    FROM YourTableName t
    JOIN RecursiveCTE r ON t.ParentID = r.ID
)
SELECT * FROM RecursiveCTE
ORDER BY ID;

方案3:MySQL 5.x(不支持递归CTE)

如果你的MySQL版本比较旧,没法用递归CTE,可以写一个自定义函数来实现路径拼接:

DELIMITER //
CREATE FUNCTION GetHierarchyPath(nodeID INT) 
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
    DECLARE path VARCHAR(255);
    DECLARE parentNodeID INT;
    DECLARE parentName VARCHAR(255);

    -- 初始化路径为当前节点名称
    SET path = (SELECT Name FROM YourTableName WHERE ID = nodeID);
    SET parentNodeID = (SELECT ParentID FROM YourTableName WHERE ID = nodeID);

    -- 循环向上查找父节点,直到根节点(ParentID=0)
    WHILE parentNodeID != 0 DO
        SET parentName = (SELECT Name FROM YourTableName WHERE ID = parentNodeID);
        SET path = CONCAT(parentName, '/', path);
        SET parentNodeID = (SELECT ParentID FROM YourTableName WHERE ID = parentNodeID);
    END WHILE;

    RETURN path;
END //
DELIMITER ;

-- 调用函数查询结果
SELECT ID, Name, ParentID, GetHierarchyPath(ID) AS Result FROM YourTableName ORDER BY ID;

注意事项

  • 记得把代码里的YourTableName替换成你实际使用的表名
  • 如果你的名称字段长度比较长,要调整字符串类型的长度(比如SQL Server用VARCHAR(MAX),MySQL可以把VARCHAR(255)改成更大的值)
  • 确保你的树形结构没有循环引用(比如子节点的ParentID指向自己或者上层节点形成环),否则递归会无限循环,SQL Server默认有100层的递归限制,必要时可以用OPTION (MAXRECURSION 0)取消限制,但不建议这么做除非你确认没有循环。

内容的提问来源于stack exchange,提问作者Ranjith S

火山引擎 最新活动