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

相关推荐
清空mega1 分钟前
第五章《Android 数据存储》
数据库·android studio
q***333731 分钟前
Redis简介、常用命令及优化
数据库·redis·缓存
武子康1 小时前
Java-168 Neo4j CQL 实战:WHERE、DELETE/DETACH、SET、排序与分页
java·开发语言·数据库·python·sql·nosql·neo4j
一 乐1 小时前
校园墙|校园社区|基于Java+vue的校园墙小程序系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·小程序
合作小小程序员小小店1 小时前
桌面开发,在线%考试管理%系统,基于eclipse,java,swing,mysql数据库。
java·数据库·mysql·eclipse·jdk
谅望者1 小时前
数据分析笔记01:数据分析概述
大数据·数据库·数据仓库·数据分析
凯子坚持 c1 小时前
从 API 到应用:用 Rust 和 SQLx 为 Axum 服务添加持久化数据库
数据库·oracle·rust
傻啦嘿哟1 小时前
爬取数据存入SQLite:轻量级数据库实战指南
数据库·sqlite
小红的布丁3 小时前
Redis存储引擎剖析:从哈希表到智能数据结构
数据库·redis