1、简介:Oracle层次化查询是Oracle特有的功能实现,主要用于返回一个数据集,这个数据集存在树的关系(数据集中存在一个Pid记录着当前数据集某一条记录的Id)。

2、层次化查询主要包含两个子句,一个start with另一个是connect by。

start with:这个子句一般用于指定层次化查询的开始节点(也就是树的最顶级节点),找到最顶级节点,然后按照一定的规则开始查找其剩余的子节点

connect by:这个子句就是上面所说的规则,用于查找剩余子节点的规则

CREATE TABLE MENU
( "ID" NUMBER,
"DATA" VARCHAR2(100),
"PID" NUMBER
)
insert into MENU (id, data, pid)values (7, 'g', 3);
insert into MENU (id, data, pid)values (1, 'a', null);
insert into MENU (id, data, pid)values (2, 'b', null);
insert into MENU (id, data, pid)values (3, 'c', 2);
insert into MENU (id, data, pid)values (4, 'd', 2);
insert into MENU (id, data, pid)values (5, 'e', 4);
insert into MENU (id, data, pid)values (6, 'f', 1);

下面开始执行层次化查询,从PId为null的节点(该节点为根节点)开始递归查找,查找出所有的更节点下的子节点,构建出一个完整的树

select ID,DATA,nvl(TO_CHAR(PID),'NULL') from menu start with PID is NULL connect by prior ID=pid

代码解析:

(1)、start with PID is NULL  指定层次化查询的根节点,

红框内的两个节点为根节点,并开始遍历其余的节点。

(2)、connect by prior ID=pid  当前节点的PID等于上一层节点的ID,如果满足条件,就加入到树结果集中

指定遍历查找子节点的规则----->  这一过程是递归查找,会一层一层找下去,直到不符合这一规则,则查找停止。

3、实现上面结果集的另一种Sql实现

select ID,DATA,nvl(TO_CHAR(PID),'NULL') from menu start with (data='a' or data='b') connect by prior ID=PID

结论:根节点的定义比较灵活,但是(connect by)遍历子节点的规则,比较固定基本都是判断父节点和子节点的ID的,如果理解了这句话,层次化查询,差不多也就理解了!

4、  Oracle SQL 中的层次化查询会检测数据中是否存在回环(死循环),如果存在回环,则会抛出 ORA-01436: CONNECT BY loop in user data . 的错误。如果在 connect by 后面加上 nocycle 则 产生回环的最后一层的节点会被删除。

如果数据中出现这种情况,产生了回环,那么在connect by 后面 加nocycle,节能

select ID,DATA,nvl(TO_CHAR(PID),'NULL') from menu start with (data='a' or data='b') connect by nocycle prior ID=PID 

just没有报错,有点郁闷,并没有删除,不知道哪里出了问题,但是至少不抱错了!!!

5、Oracle 还为层次化查询提供了一些伪列( Pseudo Column )。

(1)、CONNECT_BY_ISCYCLE 当这一行有一个子节点同时也是它的祖先节点时返回 1 ,否则返回 0 。

(2)、CONNECT_BY_ISLEAF 当这一行是叶节点时返回 1 ,否则返回 0 。伪列 LEVEL 返回这一行在树中的层次,根为第一层。

(3)、CONNECT_BY_ROOT 查询操作符可以加在 connect by 之后的某个字段之前,表示获得这一行的根节点的该字段的值。

6、层次化查询还支持一个特殊的函数 SYS_CONNECT_BY_PATH , SYS_CONNECT_BY_PATH ( exp , char ),这个函数返回从根节点到这一行计算其中每个exp 表达式的值,并把它们连接成字符串,每个节点之间用 char 字符来分割。下面是一个例子。

这个函数很棒,可以考虑其他的数据库也实现这个方法,这样我们处理一个树结构就很方便了!!!

oracle 层次化查询(生成菜单树等)的更多相关文章

  1. Java 数据库树形查询生成菜单结构

    Java 数据库树形查询 JAVA从数据库读取菜单,递归生成菜单树. 定义菜单类 public class Menu { // 菜单id private String id; // 菜单名称 priv ...

  2. Java生成菜单树(目录树)的几种方式

    本文介绍两种不同生成多级目录树的方式:1. 递归生成,2.  map+list 集合生成.最下方会附上完整代码. 生成树的基本规则:子节点的par_id等于父节点的id. 1. 实体类 import ...

  3. QMenu 设置菜单图标 & 生成菜单树

    效果图 源码 .h 文件 protected slots: void onMenuTriggered(QAction*); .cpp 文件 // 菜单 QMenu *pMenu = new QMenu ...

  4. java从数据库读取菜单,递归生成菜单树

    首先看一下菜单的样子 根据这个样子我们定义菜单类 public class Menu { // 菜单id private String id; // 菜单名称 private String name; ...

  5. java生成多级菜单树

    使用java实现一个多级菜单树结构 先上数据库 ps_pid字段很重要,是父级菜单的id Menu类 Menu类要新增一个字段,用来存放子菜单 /** * 子菜单列表 */ private List& ...

  6. vue中组件之间的相互调用,及通用后台管理系统左侧菜单树的迭代生成

    由于本人近期开始学习使用vue搭建一个后端管理系统的前端项目,在左侧生成菜单树的时候遇到了一些问题.在这里记录下 分析:由于本人设定的菜单可以使多级结构,直接使用vue的v-for 遍历并不是很方便. ...

  7. 【SQL】CONNECT BY 层次化查询

    层次化查询,顾名思义就是把查询结果有层次的呈现出来.层次化查询结果类似于树状结构,最顶端的是“根节点”,下面是“父节点”,没有子节点的是“叶节点”. 为了让一个或多个表具有层次关系,必须使用相关的字段 ...

  8. React + Antd Menu组件实现菜单树

    准备好两个变量,一个用来保存平级菜单列表,一个用来保存遍历后的菜单树. 推荐后端返回平级菜单树,假如菜单比较多,可以直接结合find方法找到菜单,做搜索功能很省事. const [menuList, ...

  9. ORACLE 树形查询 树查询

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

随机推荐

  1. Head First Python之3文件与异常

    文件基本操作 Python从文本读取数据时,一次会到达一个数据行. sketch.txt文件 Man: Is this the right room for an argument? Other Ma ...

  2. ARM汇编程序中的伪指令

    转自http://blog.chinaunix.net/uid-13701930-id-336459.html 4.1 ARM汇编器所支持的伪指令 在ARM汇编语言程序里,有一些特殊指令助记符,这些助 ...

  3. 【微服务架构】SpringCloud之Feign(五)

    Feign简介 Feign 是一个声明web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Fei ...

  4. Atcoder 2159 連結 / Connectivity(并查集+map乱搞)

    問題文N 個の都市があり.K 本の道路と L 本の鉄道が都市の間に伸びています. i 番目の道路は pi 番目と qi 番目の都市を双方向に結び. i 番目の鉄道は ri 番目と si 番目の都市を双 ...

  5. BZOJ 3884 上帝与集合的正确用法(扩展欧拉定理)

    Description   根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“ ...

  6. 再次理解js中的call函数

    a.call(b); 网上说明的版本比较多.有的说,是指针替换.有说,将a对象的方法加在b对象执行.官方说:什么对象替换什么对象.反正看了几个版本,尽管有具体的实例,看了我三次都没看懂它的具体含义.看 ...

  7. MongoDB整理笔记のjava MongoDB分页优化

    最近项目在做网站用户数据新访客统计,数据存储在MongoDB中,统计的数据其实也并不是很大,1000W上下,但是公司只配给我4G内存的电脑,让我程序跑起来气喘吁吁...很是疲惫不堪. 最常见的问题莫过 ...

  8. 利用PhotoShop对大图像进行等分切片

    图文介绍利用PhotoShop等分切图 1.调用切片工具,右键选择划分切片 2.指定水平划分.垂直划分的等分数量,点击确定 3.在文件菜单中选择存储为... 4.配置图像质量参数.点击存储.指定存储位 ...

  9. 学习做爬虫-vs2017

    最近新装了vs2017,安装过程发生了很大的变化,操作变的更加容易了. 下载vs安装程序进行安装.更新界面如图所示,我选择了安装免费个人版(这个是已安装的更新界面,和安装界面差不多) 如图所示,这样的 ...

  10. 微信开发之c#下获取jssdk的access_token

    获取access_token是调用微信JS接口的基础,只有得到了它才能得到我们需要的jsapi_ticket并生成签名,然后注入配置信息config. 微信官方文档我就不多做介绍,反正我是踩了不少坑. ...