oracle 递归 level

drop table automobiles
create table automobiles(
       part_id number(5)
         constraint pk_auto_part_id primary key,
       parent_id number(5)
         constraint fk_auto_ppid_ references  automobiles(part_id),
       part_cname varchar2(30) not null,
       part_ename varchar2(30) not null,
       mp_cost number(9,2),
       desribe varchar2(20)    
);

--插入数据
insert into automobiles values( 1,null,'汽车','mobile',84321.99,'Assembly');
insert into automobiles values( 2,1,'车身','bodywork',19892.99,'Manufacture');
insert into automobiles values( 3,1,'发送机','engine',42128,'Purchase');
insert into automobiles values( 4,1,'附件','attached',15212,'Assembly');
insert into automobiles values( 5,2,'保险杠','bumper',4812.95,'Purchase');
insert into automobiles values( 6,2,'底盘','chassis',12795.11,'Manufacture');
insert into automobiles values( 7,2,'行李箱','Boot',812.11,'Manufacture');
--分层sql脚本语句练习
select level,part_id,parent_id,part_cname,part_ename,mp_cost,desribe
from automobiles
start with part_id=1
connect by prior part_id=parent_id
order by level;
--缩进显示
select level,
    lpad(' ',2*level-1)||part_cname||' '||part_ename as partName
from automobiles
start with part_id=1
connect by prior part_id=parent_id
order by level;
--使用子查询
select level,lpad(' ',2*level-1)||part_cname||' '||part_ename as partName from automobiles
start with part_id=(select part_id from automobiles where part_cname like '%轴%')
connect by prior  part_id=parent_id
order by level;
--自底向上的遍历
select level,lpad(' ',2*level-1)||part_cname||' '||part_ename as partName
from automobiles
start with part_id=(select part_id from automobiles where part_cname like '%轴%')
connect by prior parent_id=part_id
order by level;
--删除指定的节点
select level,lpad(' ',2*level-1)||part_cname||' '||part_ename as partName from automobiles
where part_cname <> '底盘'
start with part_id=1
connect by prior parent_id=part_id
order by level
--删除分支
select level,lpad(' ',2*level-1)||part_cname||' '||part_ename as partName from automobiles
start with part_id=1
connect by prior parent_id=part_id and part_cname <> '底盘'
order by level;

### Oracle 递归查询 WITH 子句 示例教程 在 Oracle 数据库中,`WITH` 子句是一种强大的工具,可用于创建公共表达式(CTE),从而实现复杂查询的分解和重用。它不仅可以提高查询的可读性和性能,还可以支持递归操作。 #### 使用 `START WITH ... CONNECT BY PRIOR` 的传统方式 传统的 Oracle 层次化查询使用 `START WITH ... CONNECT BY PRIOR` 来处理树形结构数据[^1]。例如: ```sql SELECT employee_id, manager_id, last_name FROM employees START WITH manager_id IS NULL CONNECT BY PRIOR employee_id = manager_id; ``` 上述查询展示了如何从根节点(无上级管理者)开始遍历员工表中的层级关系。 --- #### 使用 `WITH` 子句实现递归查询 现代版本的 Oracle 支持通过 `WITH` 子句来完成递归查询,这种方式更加灵活且易于理解[^4]。以下是具体语法说明及其应用实例。 ##### 基本语法 ```sql WITH recursive_cte (column_list) AS ( -- 初始成员部分:提供基础记录集合 SELECT ... FROM some_table_or_view UNION ALL -- 递归成员部分:基于上一轮的结果继续扩展 SELECT ... FROM some_table_or_view JOIN recursive_cte ON join_condition ) -- 主查询部分:最终输出结果 SELECT * FROM recursive_cte; ``` - **初始成员** 是指递归过程的第一步,通常是从某个固定起点出发的数据集。 - **递归成员** 定义了如何利用当前轮次的结果生成新的记录。 - 这两部分通过 `UNION ALL` 结合在一起形成完整的 CTE 表达式。 --- ##### 示例 1:计算斐波那契数列 下面的例子演示了如何使用递归 `WITH` 子句生成斐波那契数列[^5]。 ```sql WITH fibonacci(n, a, b) AS ( -- 初始化阶段 SELECT 1, 0, 1 FROM DUAL UNION ALL -- 递归阶段 SELECT n + 1, b, a + b FROM fibonacci WHERE n < 10 -- 控制递归层数 ) SELECT a AS fib_value FROM fibonacci; ``` 此脚本会返回前十个斐波那契数值作为结果。 --- ##### 示例 2:模拟组织架构图 假设存在一张名为 `employees` 的表格,其中包含字段 `employee_id`, `manager_id`, 和 `last_name`。我们希望展示每位雇员与其直接下属的关系链路。 ```sql WITH emp_hierarchy(emp_id, mgr_id, level_num) AS ( -- 非递归起始条件 SELECT employee_id, manager_id, 1 FROM employees WHERE manager_id IS NULL UNION ALL -- 递归逻辑 SELECT e.employee_id, e.manager_id, eh.level_num + 1 FROM employees e INNER JOIN emp_hierarchy eh ON e.manager_id = eh.emp_id ) SELECT * FROM emp_hierarchy; ``` 该查询能够揭示整个企业内部人员之间的上下级关联情况,并附带每层深度标记。 --- ##### 示例 3:路径追踪 如果需要构建一条由父节点到叶子节点的具体路线,则可通过字符串拼接技术达成目标。 ```sql WITH path_traversal(node_id, parent_id, full_path) AS ( -- 开端设定 SELECT node_id, parent_id, TO_CHAR(node_id) FROM tree_nodes WHERE parent_id IS NULL UNION ALL -- 循环展开 SELECT tn.node_id, tn.parent_id, pt.full_path || '->' || tn.node_id FROM tree_nodes tn INNER JOIN path_traversal pt ON tn.parent_id = pt.node_id ) SELECT * FROM path_traversal; ``` 这段代码适用于任何具有父子依赖特性的场景,比如文件夹目录或者分类体系等。 --- ### 总结 无论是采用经典的 `START WITH ... CONNECT BY PRIOR` 方法还是现代化的 `WITH` 子句形式,Oracle 提供了多种途径来进行高效的递归查询操作[^2][^3]。开发者应根据实际需求选择最合适的解决方案。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值