一、简介
  在oracle中start with connect by (prior) 用来对树形结构的数据进行查询。其中start with conditon 给出的是数据搜索范围, connect by后面给出了递归查询的条件,prior 关键字表示父数据,prior 条件表示子数据需要满足父数据的什么条件。如下
start with id= '10001' connect by prior parent_id= id and prior num = 5
表示查询id为10001,并且递归查询parent_id=id,为5的记录。
二、实例
  1、构造数据

 1 -- 表结构
2 create table menu(
3 id varchar2(64) not null,
4 parent_id varchar2(64) not null,
5 name varchar2(100) not null,
6 depth number(2) not null,
7 primary key (id)
8 )
9
10 -- 初始化数据
11 -- 顶级菜单
12 insert into menu values ('100000', '0', '顶级菜单1', 1);
13 insert into menu values ('200000', '0', '顶级菜单2', 1);
14 insert into menu values ('300000', '0', '顶级菜单3', 1);
15
16 -- 父级菜单
17 -- 顶级菜单1 直接子菜单
18 insert into menu values ('110000', '100000', '菜单11', 2);
19 insert into menu values ('120000', '100000', '菜单12', 2);
20 insert into menu values ('130000', '100000', '菜单13', 2);
21 insert into menu values ('140000', '100000', '菜单14', 2);
22 -- 顶级菜单2 直接子菜单
23 insert into menu values ('210000', '200000', '菜单21', 2);
24 insert into menu values ('220000', '200000', '菜单22', 2);
25 insert into menu values ('230000', '200000', '菜单23', 2);
26 -- 顶级菜单3 直接子菜单
27 insert into menu values ('310000', '300000', '菜单31', 2);
28
29 -- 菜单13 直接子菜单
30 insert into menu values ('131000', '130000', '菜单131', 3);
31 insert into menu values ('132000', '130000', '菜单132', 3);
32 insert into menu values ('133000', '130000', '菜单133', 3);
33
34 -- 菜单132 直接子菜单
35 insert into menu values ('132100', '132000', '菜单1321', 4);
36 insert into menu values ('132200', '132000', '菜单1332', 4);
37

  生成的菜单层次结构如下:
顶级菜单1
          菜单11
          菜单12
          菜单13
                    菜单131
                    菜单132
                              菜单1321
                              菜单1322
                    菜单133
          菜单14
顶级菜单2
          菜单21
          菜单22
          菜单23
顶级菜单3
          菜单31

  2、SQL查询

--prior放的左右位置决定了检索是自底向上还是自顶向下. 左边是自上而下(找子节点),右边是自下而上(找父节点)
--找父节点
select * from menu start with id='130000' connect by id = prior parent_id;

  

--找子节点节点
-- (子节点)id为130000的菜单,以及130000菜单下的所有直接或间接子菜单(prior 在左边, prior、parent_id(等号右边)在右边)
select * from menu start with id='130000' connect by prior id = parent_id ;

  

-- (父节点)id为1321的菜单,以及1321菜单下的所有直接或间接父菜单(prior、parent_id(等号左边) 都在左边)
select * from menu start with id='132100' connect by prior parent_id = id;
-- prior 后面跟的是(parent_id) 则是查找父节点,prior后面跟的是(id)则是查找子节点

  

--根据菜单组分类统计每个菜单包含子菜单的个数
select id, max(name) name, count(1) from menu
group by id
connect by prior parent_id = id
order by id

  

-- 查询所有的叶子节点
select t2.* from menu t2 where id not in(select t.parent_id from menu t) order by id;

  

三、性能问题  

  对于 start with connect by语句的执行,oracle会进行递归查询,当数据量大的时候会产生性能相关问题。

--生成执行计划
explain plan for select * from menu start with id='132100' connect by prior parent_id = id; -- 查询执行计划
select * from table( dbms_xplan.display);

  语句执行计划结果如下:

Plan hash value: 3563250490

----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 133 | 1 (0)| 00:00:01 |
|* 1 | CONNECT BY WITH FILTERING | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID | MENU | 1 | 133 | 1 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN | SYS_C0018586 | 1 | | 1 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | | | | |
| 5 | CONNECT BY PUMP | | | | | |
| 6 | TABLE ACCESS BY INDEX ROWID| MENU | 1 | 133 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | SYS_C0018586 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - access("ID"=PRIOR "PARENT_ID")
3 - access("ID"='132100')
7 - access("ID"=PRIOR "PARENT_ID") Note
-----
- dynamic sampling used for this statement

[转载]oracle树形查询 start with connect by的更多相关文章

  1. oracle树形查询 start with connect by

    一.简介 在oracle中start with connect by (prior) 用来对树形结构的数据进行查询.其中start with conditon 给出的是数据搜索范围, connect ...

  2. 整理oracle 树形查询

    注:本文参考了<整理oracle 树形查询> sql树形递归查询是数据库查询的一种特殊情形,也是组织结构.行政区划查询的一种最常用的的情形之一.下面对该种查询进行一些总结: create ...

  3. Oracle层次查询start with connect by

    博客参考:https://www.cnblogs.com/jerryxing/articles/2339352.html start with connect by 层次查询(Hierarchical ...

  4. Oracle树形查询

    sql树形递归查询是数据库查询的一种特殊情形,也是组织结构.行政区划查询的一种最常用的的情形之一.下面对该种查询进行一些总结: start with子句: 递归的条件,需要注意的是如果with后面的值 ...

  5. ORACLE 树形查询 树查询

    前台树结构依据个人的权限登录变化 全部我查询要依据 树的ID 查询以下全部的子节点 以及本节点的信息 select * from table start with id = #{id} connect ...

  6. oracle 树形表结构查询 排序

    oracle 树形表结构排序 select * from Table start with parentid is null connect by prior id=parentid order SI ...

  7. MySql/Oracle树形结构查询

    Oracle树形结构递归查询 在Oracle中,对于树形查询可以使用start with ... connect by select * from treeTable start with id='1 ...

  8. Oracle 层次查询 connect by

      oracle 层次查询 语法:       SELECT ... FROM            [WHERE condition]                             --过 ...

  9. Oracle中树形查询使用方法

    树形查询一般用于上下级场合,使用的特殊sql语法包括level,prior,start with,connect by等,下面将就实例来说明其用法. 表定义: create table tb_hier ...

随机推荐

  1. 前端框架之Vue(1)-第一个Vue实例

    vue官方文档 知识储备 es6语法补充 let 使用 var 声明的变量的作用域是全局. { var a = 1; } console.info(a); 例1: var arr = []; for ...

  2. C++的函数功能总结

    1. string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,返回npos. 2.string的substr(pos=0, count=npos)返回字符串[pos, pos+ ...

  3. springboot + mybatis配置分页插件

    一:使用pagehelper配置分页插件 1:首先配置springboot +mybatis框架  参考:http://www.cnblogs.com/liyafei/p/7911549.html 2 ...

  4. 对k8s service的一些理解

    服务service service是一个抽象概念,定义了一个服务的多个pod逻辑合集和访问pod的策略,一般把service称为微服务 举个例子一个a服务运行3个pod,b服务怎么访问a服务的pod, ...

  5. python开源数据库gadfly安装排除错误

    从sourceforge.net上下载的,结果需要仔细看网页才能找到下载地址.下载zip包,它没有把下载地址放在显眼的地方. 安照提示,python setup.py结果提示出错.看帮助文件,需要运行 ...

  6. iOS 崩溃分析

    崩溃统计分析,在APP中是非常常见一种优化APP,发现APP的BUG的方式. 1.异常处理 可通过try catch 方式处理,如果发生异常,会走catch ,最终走fianlly.对一些我们不想他崩 ...

  7. HTTP通信机制

    HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:  1. 建立TCP连接 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接, ...

  8. Selenium基础知识(九)验证码

    关于Selenium处理验证码总结下: 1.去掉验证码(这个为了测试,去掉可能性不大) 2.万能验证码(让开发给做一个万能验证码,可能性也不大) 3.OCR光学识别,python包Python-tes ...

  9. 使用dynamic引发的异常:无法对 null 引用执行运行时绑定

    今天上午运营反映有商户的账单没有生成. 查看日志,在批量生成账单服务执行过程中,因为如下异常而中断了: 跑批异常 Microsoft.CSharp.RuntimeBinder.RuntimeBinde ...

  10. js判断当前页面是否有父页面,页面部分跳转解决办法,子页面跳转父页面不跳转解决 (原)

    //如果当前页面存在父页面,则当前页面的父页面重新加载(即子页面父页面连带跳转) if(top.location!=self.location){         window.parent.loca ...