递归CTE实战:用SQL搞定树形结构查询,告别“写死”代码
📅 2026/7/17 1:52:06
👁️ 次浏览
大家好我是小耶写功课只是为了我踩过的坑你们别再踩了你有没有写过这样的代码查组织架构先查顶层部门再循环查子部门每层写一个for循环。部门深度是5层就写5个循环深度不确定就写while循环不断查库。这种写法代码难看、性能差、还容易出bug。每次看到这种代码我都想问一句为什么不用递归CTE递归CTE是SQL标准中处理树形结构的官方解法MySQL 8.0、PostgreSQL、SQL Server都原生支持。树形结构查询有好几种写法每种写法各有优劣写法优点缺点循环查库直观容易理解代码冗长性能差N次查询递归CTE标准解法一次查询支持任意深度语法稍复杂需注意性能闭包表查询极快维护成本高适合读多写少路径枚举查询快易于理解更新路径成本高递归CTE可能是树形查询的最优解——语法简单清晰、一次搞定、不需要额外维护表结构。我把三个最常用的场景拆开讲看完就能上手。一、先搞清楚递归CTE是什么递归CTERecursive Common Table Expression说白了就是一个能“自己调用自己”的临时查询结果集。它由两部分组成锚点Anchor告诉数据库“从哪开始找”。比如查部门树的时候先找到最顶层的那个部门——WHERE parent_id IS NULL。递归成员Recursive Member告诉数据库“怎么继续往下找”。比如通过当前层的id去关联子部门的parent_id——ON d.parent_id dt.id。两部分用UNION ALL连接起来。数据库执行的时候先跑锚点拿到第一层结果然后拿着这些结果去跑递归成员拿到第二层再拿第二层去跑第三层……直到再也找不到新数据为止。整个流程可以理解成从起点出发每次拿当前查到的结果去查下一层一层层往下展开直到触底为止。就像玩一个“点开一个文件夹自动展开它里面所有子文件夹”的游戏只不过这个游戏是数据库帮你自动完成的。二、场景一遍历组织架构树——最基础的用法假设有一张部门表department字段为id、name、parent_id。要查出某个部门及其所有下级WITH RECURSIVE dept_tree AS ( -- 锚点从根部门开始 SELECT id, name, parent_id, 0 AS depth FROM department WHERE id 1 -- 指定根节点ID UNION ALL -- 递归找子部门 SELECT d.id, d.name, d.parent_id, dt.depth 1 FROM department d INNER JOIN dept_tree dt ON d.parent_id dt.id ) SELECT * FROM dept_tree ORDER BY depth, id;depth字段记录层级深度方便在应用层做缩进展示。ORDER BY depth保证了父级在子级之前输出。为什么这比循环查库好一次查询搞定所有层级不用在应用层写循环不用反复建立数据库连接性能提升肉眼可见。三、场景二面包屑导航——从叶子节点往上找电商网站的商品分类、博客的评论嵌套、系统的菜单路径——这些都需要“从当前位置追溯到根”。比如给一个商品分类ID生成“首页 手机 智能手机 iPhone 15”这样的面包屑WITH RECURSIVE breadcrumb AS ( -- 锚点从当前分类开始 SELECT id, name, parent_id, 1 AS level FROM category WHERE id 123 -- 指定当前分类ID UNION ALL -- 递归往上找父级 SELECT c.id, c.name, c.parent_id, b.level 1 FROM category c INNER JOIN breadcrumb b ON c.id b.parent_id ) SELECT * FROM breadcrumb ORDER BY level DESC;ORDER BY level DESC让根节点排在前面直接就能渲染面包屑。一层SQL搞定原本需要递归查询或多次查库才能完成的事情。四、场景三带路径的完整子树——行政区域查询有时候不仅要查出所有下级节点还要知道每个节点的完整路径。比如查询某个省下的所有市、区、街道WITH RECURSIVE region_tree AS ( -- 锚点从指定省份开始 SELECT id, name, parent_id, 0 AS depth, CAST(name AS CHAR(1000)) AS path FROM region WHERE id 440000 -- 广东省 UNION ALL -- 递归找下级行政区 SELECT r.id, r.name, r.parent_id, rt.depth 1, CONCAT(rt.path, , r.name) FROM region r INNER JOIN region_tree rt ON r.parent_id rt.id ) SELECT * FROM region_tree ORDER BY depth, id;path字段用CAST指定了足够长度CONCAT逐层拼接最终得到类似“广东省 广州市 天河区”的完整路径。这个模式在电商的SPU-SKU层级、BOM物料清单、组织权限树等场景中都非常实用。五、递归CTE的性能陷阱与避坑指南递归CTE虽强但用不好也会踩坑。陷阱1缺少索引每层全表扫描递归查询的每一层都会执行一次JOIN。如果parent_id没有索引每一层都要扫描全表性能急剧下降。解法确保parent_id上有索引。对于频繁查询树形结构的表这是必须的。陷阱2锚点写错查不出数据锚点必须明确指定根节点。用WHERE parent_id IS NULL或WHERE id 1都可以但要确保和业务数据一致。如果业务中用parent_id 0表示根节点锚点就要写成WHERE parent_id 0。陷阱3数据中存在环导致无限递归如果数据中出现A.parent_id B.id且B.parent_id A.id这样的环递归CTE会无限执行下去。解法限制递归深度。在递归成员中添加WHERE dt.depth 20这样的条件或在最外层加LIMIT。大多数数据库也提供了MAXRECURSION选项来控制最大迭代次数。陷阱4大数据量下性能下降当树形结构数据量极大百万级节点且查询频繁时递归CTE可能成为性能瓶颈。解法考虑用闭包表Closure Table或路径枚举Path Enumeration方案来替代递归CTE。这两种方案以空间换时间适合读多写少的场景。六、总结递归CTE是处理树形结构查询的标准写法三个核心场景覆盖了大部分日常需求从根到叶遍历组织架构、商品分类——WHERE parent_id IS NULL往下找从叶到根面包屑导航、权限继承——WHERE id 当前节点往上找带路径的子树行政区域、BOM清单——用CONCAT拼接完整路径递归CTE的语法看起来有点吓人但拆开看就是“锚点 UNION ALL 递归关联”三部分。写的时候记住三件事锚点写对、索引建好、防环做好剩下的就是多练。小耶在手SQL 不愁还有什么想了解的欢迎留言小耶一定知无不言言无不尽……我们下次见~
1. 项目概述:从“抓包”到“协议分析”的认知升级看到这个标题,很多朋友的第一反应可能是:“哦,不就是用Frida去Hook某个App的登录或者请求,把加密参数打印出来吗?” 如果你也这么想,那说明你可…
📅 2026/7/17 1:52:06
1. Linux系统时间管理的重要性作为一名运维工程师,我每天都要面对数十台甚至上百台Linux服务器的监控和维护工作。其中,系统运行时间的监控是最基础也最关键的指标之一。记得刚入行时,有次线上服务突然中断,排查了半天才发现是服务…
📅 2026/7/17 1:52:06
本文还有配套的精品资源,点击获取
简介:直接扔进服务器就能跑的PHP图片处理小工具,不用装环境、不依赖数据库。主要干两件事:一是在图片上加PNG水印,位置(左上/居中/右下等)、偏移像素、缩放…
📅 2026/7/17 1:52:06
做贸易数据的朋友,应该都听过CEPII吧。就是那个BACI数据库,还有那个著名的Gravity Model。很多人刚上手的时候,都懵圈。特别是那个dist和geo,看着都差不多。都是算距离嘛,有啥区别?今天我就结合我这几年的踩坑经验,聊聊这个。不整那些虚头巴脑的理论,只说大白话。先说结…
📅 2026/7/17 2:28:33
本文还有配套的精品资源,点击获取
简介:双击就能用的学生信息管理系统,内置studentsystem.exe,不依赖Python环境,适合零基础用户快速上手;附带全部Python源代码,结构清晰,含stude…
📅 2026/7/17 2:28:17
1. 项目概述:AI时代的Chrome插件快速开发最近在技术社区看到一个很有意思的案例:有人仅用10分钟就完成了一个功能完整的Chrome插件开发。这听起来像是天方夜谭,但当我深入了解后发现,这背后是Prompt编程技术带来的开发效率革命。作…
📅 2026/7/17 2:28:17
1. OpenClaw不是“另一个ChatUI”,它是Windows上能真正动手干活的AI智能体你有没有试过在Windows上装一个AI助手,结果卡在Python环境、CUDA版本、模型路径、端口冲突这四座大山之间?我去年帮三个不同行业的客户部署本地AI工具,平均…
📅 2026/7/17 2:28:17
本文还有配套的精品资源,点击获取
简介:专为Arduino平台优化的MS5837传感器驱动库,兼容MS5837-30BA(0–30 bar,最大300米水深)和MS5837-02BA(0–2 bar,适用于大气压与海拔高度测量…
📅 2026/7/17 2:28:17
1. Sysprep工具概述Sysprep(System Preparation Tool)是微软提供的一款系统准备工具,主要用于Windows操作系统的镜像准备和部署。作为IT管理员在大规模部署Windows环境时的利器,它能够有效解决硬件差异带来的兼容性问题。这个工具…
📅 2026/7/17 2:28:17
1. 为什么选择用DeepSeek V4替换Codex的底座模型去年我在开发一个智能代码补全工具时,发现Codex的默认底座模型在复杂业务逻辑场景下表现不尽如人意。经过多次测试对比,DeepSeek V4在以下几个关键指标上展现出明显优势:代码补全准确率&#x…
📅 2026/7/17 0:00:32
1. VS Code 高效配置基础作为一款轻量级但功能强大的代码编辑器,VS Code 的默认配置已经能满足基本需求,但通过合理调整设置可以大幅提升编码效率。我使用 VS Code 已经有五年多时间,期间尝试过各种配置方案,总结出这套适合大多数…
📅 2026/7/17 0:00:32
在异常检测领域,很多优秀算法最初都是以研究代码的形式发布的。它们能够在固定测试集上复现实验结果,却不一定能被普通用户直接拿来测试自己的图片。尤其是最近很多算法仅提供在固定测试集的测试环境,而gradio的demo演示也不会提供。
对工程应用和在自己的图片上进行测试来…
📅 2026/7/17 0:00:32
豆包openclaw最近圈子里都在聊豆包openclaw,我也没忍住,掏腰包入手了一套。说实话,刚拿到手的时候,心里是打鼓的。毕竟市面上类似的智能硬件太多了,有的吹得天花乱坠,用起来却是一堆bug。为了不让大家的钱打水漂,我连续用了半个月。从开箱到日常高频使用,甚至故意测试它…
📅 2026/7/15 22:51:06
SQLyog 13.3.1 社区版在Windows 10/11上的完整安装与连接指南 对于刚接触MySQL数据库管理的开发者和学生来说,选择一个直观易用的图形化管理工具至关重要。SQLyog作为一款轻量级但功能强大的MySQL GUI工具,能够显著提升数据库操作的效率和体验。本文将详…
📅 2026/7/16 21:45:29
SPEC CPU 2006 跨平台基准测试深度实战:ARM/X86/MIPS 架构配置优化与结果分析方法论在当今多元化的计算架构时代,如何客观评估不同处理器平台的真实性能成为系统工程师和性能优化专家的核心挑战。SPEC CPU 2006 作为业界公认的计算密集型基准测试套件&am…
📅 2026/7/16 14:13:12
目录
第一步:选对模板,省心一半
第二步:打开扫码点餐功能
开启功能按钮
桌台管理与桌码生成
第三步:个性化设计,打造品牌感
调整点餐页面
设置点餐规则 你还在让顾客站着排队点餐吗?2025年ÿ…
📅 2026/7/15 22:46:06
在业务中快速构建一个能理解私有文档、准确回答专业问题的智能助手,是很多开发团队面临的共同挑战。传统方案往往需要从零开始搭建复杂的 RAG(检索增强生成)系统,涉及文档解析、向量化、检索、大模型调用等多个环节,整…
📅 2026/7/16 4:59:31
FAE放射组学分析工具:医学影像特征探索的完整解决方案 【免费下载链接】FAE FeAture Explorer 项目地址: https://gitcode.com/gh_mirrors/fae/FAE
你是否曾经面对海量医学影像数据感到无从下手?想要从CT、MRI等影像中提取有价值的定量特征&#…
📅 2026/7/15 22:51:03