Oracle语法之递归查询方式

 更新时间:2025年11月13日 11:11:34   作者:苏生Susheng  
Oracle递归查询用于处理层次结构数据,通过WITH子句定义递归起始和终止条件,使用UNION ALL连接结果,适用于组织架构、产品类别、树状结构、图结构和日期范围查询,注意性能问题,使用索引、剪枝等优化

递归查询

  • Oracle的递归查询是指在一个查询语句中使用自引用的方式进行循环迭代查询。
  • 它可以用于处理具有层次结构的数据,如组织架构、产品类别等。
  • 递归查询通常使用WITH子句来定义递归查询的起始条件和终止条件,并使用UNION ALL运算符来连接递归查询的结果。

使用场景

递归查询在以下场景中经常被使用:

  1. 组织架构查询:递归查询可以用于查找组织架构的层次结构,例如查询某个员工的上级、下属或者所有下属。

  2. 产品类别查询:递归查询可以用于查询产品类别的层次结构,例如查询某个类别的所有子类别或者找到某个产品所属的所有类别。

  3. 树状结构查询:递归查询可以用于查询树状结构的层次关系,例如查询文件系统的目录结构、查询城市的层级关系等。

  4. 图结构查询:递归查询可以用于查询图结构的相关信息,例如查询社交网络中某个人的朋友列表、查询电影的相关推荐等。

  5. 日期范围查询:递归查询可以用于查询一个连续的日期范围内的数据,例如查询某个日期范围内的销售数据或者某个日期范围内的日志信息。

备注

  • 需要注意的是,在使用递归查询时要注意性能问题,特别是当数据量较大时。
  • 为了避免性能问题,可以使用递归查询的剪枝功能、添加适当的索引或者使用其他优化技巧来提升查询效率。
  • 此外,对于复杂的递归查询,可能需要考虑使用存储过程或者递归SQL重写来优化查询性能。

语法

SELECT * FROM TABLE WHERE 条件3 START WITH 条件1 CONNECT BY 条件2;

相关属性解释

  • start with [condition]: 设置起点,用来限制第一层的数据,或者叫根节点数据;以这部分数据为基础来查找第二层数据,然后以第二层数据查找第三层数据以此类推。省略后默认以全部行为起点。

  • connect by [condition] : 用来指明在查找数据时以怎样的一种关系去查找;比如说查找第二层的数据时用第一层数据某个字段进行匹配,如果这个条件成立那么查找出来的数据就是第二层数据,同理往下递归匹配。

  • prior : 表示上一层级的标识符。经常用来对下一层级的数据进行限制。不可以接伪列。prior在等号前面和后面,查询的数据是不一样的

  • level : 伪列(关键字),代表树形结构中的层级编号(数字序列结果集),这个必须配合connect by使用,和rownum是同等效果。

  • connect_by_root : 显示根节点列。经常用来分组。

  • connect_by_isleaf : 1是叶子节点,0不是叶子节点。在制作树状表格时必用关键字。

  • sys_connect_by_path() : 将递归过程中的列进行拼接。

  • nocycle、connect_by_iscycle: 在有循环结构的查询中使用。

  • siblings : 保留树状结构,对兄弟节点进行排序。

案例

基本使用

假设我们要创建一个员工表,包含员工ID、姓名和上级ID字段。我们可以按照以下方式创建表结构并插入一些数据:

CREATE TABLE employees (
    employee_id NUMBER,
    name VARCHAR2(50),
    manager_id NUMBER
);

INSERT INTO employees VALUES (1, 'Alice', NULL);
INSERT INTO employees VALUES (2, 'Bob', 1);
INSERT INTO employees VALUES (3, 'Charlie', 2);
INSERT INTO employees VALUES (4, 'Dave', 2);
INSERT INTO employees VALUES (5, 'Eve', 1);

现在我们可以编写两个递归查询,一个向上查找某个员工的所有上级,一个向下查找某个员工的所有下级。

向上递归查询可以使用CONNECT BY PRIOR关键字:

-- 向上递归查询
SELECT employee_id, name
FROM employees
START WITH name = 'Charlie' -- 起始条件
CONNECT BY PRIOR manager_id = employee_id -- 递归条件
ORDER BY level DESC;

结果将返回:

EMPLOYEE_ID | NAME
-----------------
1            Alice
2            Bob
3            Charlie

向下递归查询可以使用CONNECT BY关键字:

-- 向下递归查询
SELECT employee_id, name
FROM employees
START WITH name = 'Alice' -- 起始条件
CONNECT BY PRIOR employee_id = manager_id -- 递归条件
ORDER BY level;

结果将返回:

EMPLOYEE_ID | NAME
-----------------
1            Alice
2            Bob
3            Charlie
4            Dave
5            Eve

这样,我们就可以通过递归查询在员工表中向上或向下查找员工的上级或下级关系。

升级版-带上递归查询的属性

假设我们要创建一个部门表,包含部门ID、部门名称和上级部门ID字段。我们可以按照以下方式创建表结构并插入一些数据:

CREATE TABLE departments (
    department_id NUMBER,
    department_name VARCHAR2(50),
    parent_department_id NUMBER
);

INSERT INTO departments VALUES (1, 'Sales', NULL);
INSERT INTO departments VALUES (2, 'Marketing', 1);
INSERT INTO departments VALUES (3, 'Finance', 1);
INSERT INTO departments VALUES (4, 'Operations', NULL);
INSERT INTO departments VALUES (5, 'Advertising', 2);

现在我们可以编写一个递归查询,查找某个部门的所有下级部门,并包含递归查询的属性。

-- 递归查询部门及其下级部门
SELECT CONNECT_BY_ROOT department_id AS root_department_id,
       d.department_id,
       d.department_name,
       d.parent_department_id,
       LEVEL
FROM departments d
START WITH department_id = 1 -- 起始条件
CONNECT BY PRIOR department_id = parent_department_id -- 递归条件
ORDER BY root_department_id, LEVEL;

结果将返回:

ROOT_DEPARTMENT_ID | DEPARTMENT_ID | DEPARTMENT_NAME | PARENT_DEPARTMENT_ID | LEVEL
-----------------------------------------------------------------------------------
1                   1               Sales             null                   1
1                   2               Marketing         1                      2
1                   5               Advertising       2                      3
1                   3               Finance           1                      2
4                   4               Operations        null                   1

在查询结果中,ROOT_DEPARTMENT_ID代表根部门的ID,DEPARTMENT_ID代表当前部门的ID,DEPARTMENT_NAME代表当前部门的名称,PARENT_DEPARTMENT_ID代表当前部门的上级部门ID,LEVEL代表当前部门在层级结构中的级别。

这样,我们可以通过递归查询在部门表中查找某个部门的所有下级部门,并获得相关属性的信息。

总结

  • Oracle的递归查询是一种强大的功能,可以用于处理具有层次结构的数据(如组织架构、树形结构等)。
  • 递归查询基于CONNECT BY和PRIOR关键字,可以在SQL语句中实现递归的操作。

在使用Oracle的递归查询时,需要注意以下几点:

  1. 递归查询的起始条件:使用START WITH子句来指定递归查询的起始条件,即从哪个节点开始递归。
  2. 递归查询的递归条件:使用CONNECT BY PRIOR子句来指定递归查询的递归条件,即如何从一个节点递归到下一个节点。
  3. 递归查询的属性:在递归查询中,可以使用CONNECT_BY_ROOT关键字来获取根节点的属性,使用LEVEL关键字来获取当前节点在层次结构中的级别。
  4. 递归查询的排序:通过ORDER BY子句可以对递归查询的结果进行排序,可以按照根节点、级别等进行排序。
  5. 递归查询的限制:在处理大型数据集时,递归查询可能导致性能问题,可以通过设置递归查询的最大深度(MAXDEPTH)或者使用剪枝条件(PRUNE)来限制递归查询的范围。

递归查询在实际应用中有很多使用场景,例如处理组织架构、查找树形结构的子节点或父节点、获取层级结构的路径等。通过合理使用递归查询,可以简化复杂的数据处理操作,提高查询效率和代码的可读性。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • oracle中exp,imp的使用详解

    oracle中exp,imp的使用详解

    这篇文章主要介绍了oracle中exp,imp的使用详解,需要的朋友可以参考下
    2015-07-07
  • 解决maven不能下载oracle jdbc驱动的问题

    解决maven不能下载oracle jdbc驱动的问题

    这篇文章主要介绍了解决maven不能下载oracle jdbc驱动的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • VS2015连接Oracle数据库的详细步骤

    VS2015连接Oracle数据库的详细步骤

    这篇文章主要介绍了VS2015连接Oracle数据库的详细步骤,需要的朋友可以参考下
    2017-10-10
  • 解析jdbc处理oracle的clob字段的详解

    解析jdbc处理oracle的clob字段的详解

    本篇文章是对jdbc处理oracle的clob字段进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • Oracle安装卸载图文教程详解

    Oracle安装卸载图文教程详解

    这篇文章主要为大家介绍了Oracle安装卸载的详细图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Oracle 中XML处理函数介绍

    Oracle 中XML处理函数介绍

    本文主要介绍Oracle中XML函数的基本使用方法,希望对大家有所帮助。
    2016-05-05
  • centos7.7安装oracle11g脚本(推荐)

    centos7.7安装oracle11g脚本(推荐)

    这篇文章主要介绍了centos7.7安装oracle11g脚本,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • Oracle中行转列与行转列的实现方法

    Oracle中行转列与行转列的实现方法

    行转列和列转行是数据处理中常见的操作,可以将原始数据的行和列进行转换,以满足特定的需求,本文给大家详细介绍了Oracle中行转列与行转列的实现方法,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2024-07-07
  • Oracle中的索引讲解

    Oracle中的索引讲解

    这篇文章介绍了Oracle中的索引,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • Oracle数据库恢复教程之resetlogs操作

    Oracle数据库恢复教程之resetlogs操作

    这篇文章主要给大家介绍了关于Oracle数据库恢复教程之resetlogs操作的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Oracle数据库具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05

最新评论