Oracle递归查询树形数据

实际生活有很多树形结构的数据,比如公司分为多个部门、部门下分为多个组,组下分为多个员工;省市县的归属;页面菜单栏等等。

如果想查询某个节点的父节点或者子节点,一般通过表自身连接完成,但如果该节点的子节点还有很多层结构,就需要使用递归调用。但如果数据量特别大,递归的次数指数级上升,而且查询数据库的次数也指数级上升,导致程序和数据库压力剧增,查询时间特别长。

start with connect by prior 递归查询

1、数据准备

c 复制代码
create table area_test(
id number(10) not null,
parent_id number(10),
name varchar2(255) not null
);
alter table area_test add (constraint district_pk primary key (id));
insert into area_test (ID, PARENT_ID, NAME) values (1, null, '中国');
insert into area_test (ID, PARENT_ID, NAME) values (11, 1, '河南省');
insert into area_test (ID, PARENT_ID, NAME) values (12, 1, '北京市');
insert into area_test (ID, PARENT_ID, NAME) values (111, 11, '郑州市');
insert into area_test (ID, PARENT_ID, NAME) values (112, 11, '平顶山市');
insert into area_test (ID, PARENT_ID, NAME) values (113, 11, '洛阳市');
insert into area_test (ID, PARENT_ID, NAME) values (114, 11, '新乡市');
insert into area_test (ID, PARENT_ID, NAME) values (115, 11, '南阳市');
insert into area_test (ID, PARENT_ID, NAME) values (121, 12, '朝阳区');
insert into area_test (ID, PARENT_ID, NAME) values (122, 12, '昌平区');
insert into area_test (ID, PARENT_ID, NAME) values (1111, 111, '二七区');
insert into area_test (ID, PARENT_ID, NAME) values (1112, 111, '中原区');
insert into area_test (ID, PARENT_ID, NAME) values (1113, 111, '新郑市');
insert into area_test (ID, PARENT_ID, NAME) values (1114, 111, '经开区');
insert into area_test (ID, PARENT_ID, NAME) values (1115, 111, '金水区');
insert into area_test (ID, PARENT_ID, NAME) values (1121, 112, '湛河区');
insert into area_test (ID, PARENT_ID, NAME) values (1122, 112, '舞钢市');
insert into area_test (ID, PARENT_ID, NAME) values (1123, 112, '宝丰市');
insert into area_test (ID, PARENT_ID, NAME) values (11221, 1122, '尚店镇');

2、start with connect by prior 递归 查询 [ˈpraɪə®] 先前的

1)start whit 子句:遍历起始条件。如果要查父节点,这里可以用子节点的列,反之则反。

2)connect by 子句:连接条件。prior跟父节点列parent_id放在一起。就是往父节点方向遍历。prior跟子节点列sub_id放在一起,则往叶子节点方向遍历。parent_id、id两列谁放在"="前都无所谓,关键是prior跟谁在一起。

3)order by 子句:排序

常用的select项:

level:级别

connect_by_root:根节点

sys_connect_by_path:递归路径

其实,如果单层结构,使用表自身连接也可以实现:

2、查询所有父节点

3、查询指定节点的根节点

3、with递归查询

3.1 with递归子类

WITH TMP /*(id, parent_id, name) */

AS

(SELECT ID, PARENT_ID, NAME FROM AREA_TEST WHERE NAME = '平顶山市')

SELECT ID, PARENT_ID, NAME

FROM AREA_TEST

WHERE NAME = '平顶山市'

UNION ALL

SELECT D.ID, D.PARENT_ID, D.NAME

FROM TMP, AREA_TEST D

WHERE TMP.ID = D.PARENT_ID

3.2 with递归父类

相关推荐
njidf6 分钟前
Python上下文管理器(with语句)的原理与实践
jvm·数据库·python
F1FJJ22 分钟前
Shield CLI v0.3.0:插件系统上线,首发 MySQL Web 管理
网络·数据库·网络协议·mysql·容器·golang
波波七25 分钟前
maven导入spring框架
数据库·spring·maven
深蓝轨迹26 分钟前
Redis 分布式锁实现流程
数据库·redis·分布式
程序猿阿伟28 分钟前
《OpenClaw端口通信失效全解:监听修改与防火墙规则落地指南》
服务器·数据库·windows
进击的雷神28 分钟前
突破增量抓取困境:基于数据库状态判断的高效新闻爬虫设计
数据库·爬虫·spiderflow
一叶飘零_sweeeet32 分钟前
击穿 MySQL 事务隔离级别:底层实现原理 + 生产级架构选型避坑指南
数据库·mysql·架构·mysql事务隔离级别
虾..34 分钟前
Linux 五种IO模型
linux·服务器·数据库
程序边界41 分钟前
深度Oracle替换工程实践的技术解读(上篇)
数据库·oracle
2401_831824961 小时前
RESTful API设计最佳实践(Python版)
jvm·数据库·python