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递归父类

相关推荐
阿成学长_Cain8 小时前
Linux ipcs 命令超全详解:查看共享内存 / 消息队列 / 信号量,IPC 运维必备
linux·运维·服务器·网络·数据库
OceanBase数据库官方博客10 小时前
OceanBase AI 时代,数据库的变与不变(技术解析与实践)
数据库·人工智能·oceanbase
阿成学长_Cain12 小时前
Linux dirs命令详解|Bash目录堆栈管理快速切换目录实战教程
linux·运维·前端·数据库
ywl47081208712 小时前
Mysql 平衡二叉树、红黑树、B树、B+树区别以及应用场景(五)
数据库·b树·mysql
IvorySQL12 小时前
IvorySQL Agent 探索与实践
数据库·人工智能·postgresql·oracle·ivorysql
SelectDB13 小时前
美团数十 PB 规模 Apache Doris 实践:从统一 OLAP 到 AI-Native 数据基座
大数据·数据库·性能优化
Database_Cool_13 小时前
阿里云RDS主从延迟解决方案_只读实例半同步复制最佳实践
数据库·人工智能
KaMeidebaby14 小时前
卡梅德生物技术快报|小 RNA 适配体合成 + 多方法亲和力表征全流程标准化操作手册
前端·网络·数据库·人工智能·算法
卓怡学长14 小时前
w269基于spring boot + vue 候鸟监测数据管理系统
java·数据库·spring boot·spring·intellij-idea
ClouGence15 小时前
MySQL 到 StarRocks 数据迁移同步:同步方案与实践指南
数据库·mysql