当前位置: 首页 > news >正文

SQL WITH RECURSIVE 递归

递归查询是SQL中一种强大的功能,允许您查询具有层次结构或树形结构的数据。它通过公用表表达式(CTE)实现,特别是使用WITH RECURSIVE语法。

WITH RECURSIVE 是 SQL 中用于实现递归查询的强大特性,它允许你编写能够引用自身的查询,非常适合处理层次结构或图状数据。


基本工作原理

递归查询由三个关键部分组成:

  1. 非递归项(初始查询):这是递归的起点,提供初始结果集

  2. 递归项:这部分引用正在定义的临时表自身

  3. 终止条件:当递归不再产生新行时停止

执行流程

递归查询的执行遵循以下步骤:

  1. 首先执行非递归部分,生成初始结果集(称为"锚成员")

  2. 然后重复执行递归部分,每次使用前一次迭代的结果作为输入

  3. 当递归部分不再产生新行时,递归终止

  4. 将所有迭代的结果合并为最终结果


WITH RECURSIVE 递归表名 AS (
    -- 非递归部分(初始查询)
    SELECT 初始列 FROM 初始表 WHERE 初始条件
    
    UNION [ALL]
    
    -- 递归部分
    SELECT 递归列 FROM 递归表名 JOIN 其他表 ON 连接条件 WHERE 递归条件
)
SELECT * FROM 递归表名;

常见应用场景

1. 组织层次结构(查找所有下属)

WITH RECURSIVE employee_hierarchy AS (
    -- 基础查询:选择顶级经理
    SELECT id, name, manager_id, 1 AS level
    FROM employees
    WHERE manager_id IS NULL
    
    UNION ALL
    
    -- 递归查询:选择下属
    SELECT e.id, e.name, e.manager_id, eh.level + 1
    FROM employees e
    JOIN employee_hierarchy eh ON e.manager_id = eh.id
)
SELECT * FROM employee_hierarchy ORDER BY level, id;

2. 路径查找(查找所有路径)

WITH RECURSIVE path_finder AS (
    -- 基础查询:起点
    SELECT id, point_a, point_b, CAST(point_a AS VARCHAR) || '->' || point_b AS path
    FROM routes
    WHERE point_a = 'A'
    
    UNION ALL
    
    -- 递归查询:扩展路径
    SELECT r.id, r.point_a, r.point_b, pf.path || '->' || r.point_b
    FROM routes r
    JOIN path_finder pf ON r.point_a = pf.point_b
    WHERE pf.path NOT LIKE '%' || r.point_b || '%' -- 避免循环
)
SELECT * FROM path_finder;

3. 物料清单(BOM)展开

WITH RECURSIVE bom_expansion AS (
    -- 基础查询:顶级产品
    SELECT component_id, parent_id, quantity, 1 AS level
    FROM bom
    WHERE parent_id = 'PRODUCT_X'
    
    UNION ALL
    
    -- 递归查询:子组件
    SELECT b.component_id, b.parent_id, b.quantity * be.quantity, be.level + 1
    FROM bom b
    JOIN bom_expansion be ON b.parent_id = be.component_id
)
SELECT * FROM bom_expansion ORDER BY level, component_id;

注意事项

  1. 递归深度限制:大多数数据库有默认递归深度限制(如100或1000),可以通过配置调整

  2. 循环检测:需要确保数据没有循环引用,否则可能导致无限递归

  3. 性能:递归查询可能对大型层次结构性能较差,考虑使用物化路径或嵌套集等替代方案

相关文章:

  • 【区块链安全 | 第十八篇】类型之引用类型(二)
  • 开源深度学习框架PyTorch
  • 为什么要指针压缩,为什么能指针压缩?原理是什么?
  • 01小游戏
  • 3月31号
  • lib-zo,C语言另一个协程库,激活文件IO操作协程化
  • http知识点
  • 2025年浙江省中等职业学校职业能力大赛(学生技术技能类)“移动应用与开发”赛项技术文件
  • FFTW库在vs2022下编译lib库及在QT6.8中调用
  • LeetCode hot 100—二叉搜索树中第K小的元素
  • 【VUE2】综合练习——智慧商城
  • visio导出pdf公式变形
  • Embedding原理
  • zk基础—1.一致性原理和算法一
  • 《算法:递归+记忆化搜索》
  • 【计算机视觉】OpenCV实战项目- 抖音动态小表情
  • ESP32移植Openharmony外设篇(11) mfrc522射频读卡器
  • 数据处理与机器学习入门
  • MyBatisPlus不等于如何使用
  • qml 中的anchors
  • mindmanager网站建设流程图/百度搜索关键词查询
  • IC 网站建设/关联词有哪些
  • wordpress导航站模版/防城港网站seo
  • 怎样建设香港网站/制作网站要找什么公司
  • 南川网站制作/b站推广入口
  • app定制公司/新乡网站seo