SQL 如何用递归查询计算组织架构的完整路径字符串
发布时间 - 2026-01-26 00:00:00 点击率:次递归查询必须使用 WITH RECURSIVE,普通 CTE 不支持;各数据库语法差异大,MySQL 8.0 需显式设递归深度并用 COALESCE 防 NULL 截断路径,SQL Server 的 hierarchyid 高效但不通用。
递归查询必须用 WITH RECURSIVE,普通 CTE 不行
PostgreSQL、SQL Server、Oracle、SQLite 3.8.3+ 和 MySQL 8.0+ 都支持递归 CTE,但语法和限制差异大。核心是 WITH RECURSIVE 关键字——漏掉 RECURSIVE 会导致语法错误(如 PostgreSQL 报错 recursive query "t" does not have a recursive term)。MySQL 8.0 要求递归必须有终止条件(比如 level
cte_max_recursion_depth 截断。
路径拼接要用字符串连接 + COALESCE 处理根节点
组织架构中根节点的 parent_id 通常为 NULL 或 0,直接用 parent_path || '/' || name 会因 NULL 导致整条路径变 NULL。必须用 COALESCE 或 CONCAT(MySQL)兜底:
SELECT id, name, CAST(name AS VARCHAR(500)) AS path
FROM orgs WHERE parent_id IS NULL
UNION ALL
SELECT o.id, o.name,
COALESCE(t.path || ' / ', '') || o.name AS path
FROM orgs o
INNER JOIN t ON o.parent_id = t.id
注意:CAST 初始路径为足够长的字符串类型,避免后续拼接时被截断(尤其 SQL Server 对 VARCHAR 默认长度敏感)。
MySQL 8.0 需显式设递归深度,且不支持反向路径生成
MySQL 默认 cte_max_recursion_depth = 100,若组织层级超深(如 200 层),查不到完整路径。需在语句前加:
SET SESSION cte_max_recursion_depth = 500;
另外,MySQL 的 CONCAT 在遇到 NULL 时返回 NULL,不能像 PostgreSQL 那样靠 || 自动跳过;必须写成:
CONCAT(COALESCE(t.path, ''), ' / ', o.name)
如果要从叶子节点向上拼路径(比如“技术部 / 后端组 / Java 小组”),MySQL 不支持从下往上递归(无类似 CONNECT BY PRIOR 的反向引用),只能先查出所有祖先再聚合,或改用应用层处理。
SQL Server 的 hierarchyid 虽快但不通用
SQL Server 提供 hierarchyid 类型,能高效存储和查询树形结构,/1/2/3/ 这种路径可直接用 .ToString() 获取,性能远超递归 CTE。但它只存在于 SQL Server,迁移成本高;而且一旦用它,就不能再用标准 SQL 的 WITH RECURSIVE 写法——二者是互斥方案。如果团队未来可能换数据库,优先用标准递归 CTE,哪怕慢一点。
路径长度和层级深度容易被低估,尤其是测试数据只有 3 层,上线后发现某部门嵌套了 12 层,cte_max_recursion_depth 或字段长度不够就直接报错或截断。留余量比事后排查更省时间。
# mysql
# oracle
# java
# session
# 后端
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
iOS发送验证码倒计时应用
Laravel定时任务怎么设置_Laravel Crontab调度器配置
如何在宝塔面板创建新站点?
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
Laravel怎么清理缓存_Laravel optimize clear命令详解
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
历史网站制作软件,华为如何找回被删除的网站?
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
如何在不使用负向后查找的情况下匹配特定条件前的换行符
node.js报错:Cannot find module 'ejs'的解决办法
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
PHP 500报错的快速解决方法
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
大连网站制作公司哪家好一点,大连买房网站哪个好?
如何在局域网内绑定自建网站域名?
百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏
如何在Windows 2008云服务器安全搭建网站?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
b2c电商网站制作流程,b2c水平综合的电商平台?
Laravel如何保护应用免受CSRF攻击?(原理和示例)
详解Huffman编码算法之Java实现
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
Laravel如何实现本地化和多语言支持?(i18n教程)
如何制作一个表白网站视频,关于勇敢表白的小标题?
高防服务器:AI智能防御DDoS攻击与数据安全保障
Laravel怎么在Controller之外的地方验证数据
Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
Android 常见的图片加载框架详细介绍
Laravel如何创建自定义Facades?(详细步骤)
如何在VPS电脑上快速搭建网站?
Laravel如何使用withoutEvents方法临时禁用模型事件
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】

