为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的。

Oracle中的select语句可以用start with ... connect by prior ...子句实现递归查询,connect by 是结构化查询中用到的,其基本语法是:

select ... from 
where <过滤条件,用于对返回的所有记录进行过滤>
start with <根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树>
connect by [prior] <连接条件,其中用prior表示上一条记录,比如:connect by prior t.id = t.parent_id就是说上一条记录的id 是本条记录的parent_id,即本记录的父亲是上一条记录> 
下面我们直接来看实例,查询'KING'的所有下属雇员。SQL语句如下:

  1. select *
  2. from scott.emp e
  3. start with e.ename = 'KING'
  4. connect by prior e.empno = e.mgr;

我们再来看另外一个实例,反过来查询'SMITH'的所有上司。SQL语句如下:

  1. select *
  2. from scott.emp e
  3. start with e.ename = 'SMITH'
  4. connect by e.empno = prior e.mgr;

通过上面的两个实例,估计大家应该理解的差不多了,接下来介绍connect by的几个固定搭档。

1、sys_connect_by_path函数
语法:sys_connect_by_path(列名, '分隔符')。
作用:从start with的地方开始遍历,将遍历到的路径根据函数中的分隔符,组成一个新的字符串。

  1. select sys_connect_by_path(ename, '/') ename_tree
  2. from scott.emp
  3. start with ename = 'KING'
  4. connect by mgr = prior empno;

插个题外话,介绍sys_connect_by_path函数使用的一个小技巧,把查询行转换成列,把表emp的所有列名以'|'分隔开输出(提示:大家可以把下面的语句拆开来逐个分析),SQL语句如下:

  1. select max(ltrim(sys_connect_by_path(column_name, '|'), '|')) column_names
  2. from (select column_name, rownum rnum
  3. from user_tab_columns
  4. where table_name = 'EMP')
  5. start with rnum = 1
  6. connect by rnum = rownum;

2、level:在结构化查询结果中,每一行都是结构中的一个节点,level表示该节点在结构中的层次,根节点为1,根节点的子节点为2,以此类推。
下面SQL语句很直观的展示效果:

  1. select ename, sys_connect_by_path(ename, '/') ename_tree, level
  2. from scott.emp
  3. start with ename = 'KING'
  4. connect by mgr = prior empno;

3、connect_by_root:用在列名之前,返回当前节点的根节点对应列的值。connect_by_isleaf:返回当前节点是否为叶子节点,“是”返回1,“否”返回0。
下面SQL语句很直观的展示效果:

  1. select sys_connect_by_path(ename, '/') ename_tree,
  2. connect_by_root ename as root,
  3. connect_by_isleaf as isleaf
  4. from scott.emp e
  5. start with e.ename = 'KING'
  6. connect by prior e.empno = e.mgr;
http://blog.csdn.net/feier7501/article/details/21811319
 
转自:http://blog.csdn.net/feier7501/article/details/21815691 

创建表,初始化数据;

  1. CREATE TABLE TB_COMPANY
  2. (
  3. COMPANY_ID INTEGER PRIMARY KEY,
  4. COMPANY VARCHAR2(256),
  5. UP_COMPANYID INTEGER
  6. );
  7. INSERT INTO TB_COMPANY VALUES (0, '总公司', NULL);
  8. INSERT INTO TB_COMPANY VALUES (1, '北京分公司', 0);
  9. INSERT INTO TB_COMPANY VALUES (2, '上海分公司', 0);
  10. INSERT INTO TB_COMPANY VALUES (3, '海淀区分部', 1);
  11. INSERT INTO TB_COMPANY VALUES (4, '东城区分部', 1);
  12. INSERT INTO TB_COMPANY VALUES (5, '黄埔区分部', 2);
  13. INSERT INTO TB_COMPANY VALUES (6, '静安区分部', 2);
  14. COMMIT;

全部数据:

递归查询SQL:

  1. SELECT (RPAD(' ', 2*(LEVEL-1), '-' ) || COMPANY) COMPANY_NAME, CONNECT_BY_ROOT COMPANY, CONNECT_BY_ISLEAF, LEVEL , SYS_CONNECT_BY_PATH(COMPANY, '/')
  2. FROM TB_COMPANY
  3. START WITH UP_COMPANYID IS NULL
  4. CONNECT BY PRIOR COMPANY_ID = UP_COMPANYID;

结果:

说明:

1. CONNECT_BY_ROOT 返回当前节点的最顶端节点 
2. CONNECT_BY_ISLEAF 判断是否为叶子节点,如果这个节点下面有子节点,则不为叶子节点 
3. LEVEL 伪列表示节点深度 
4. SYS_CONNECT_BY_PATH函数显示详细路径,并用“/”分隔

递归查询SQL:

  1. SELECT * FROM TB_COMPANY START WITH COMPANY_ID = 1 CONNECT BY PRIOR COMPANY_ID = UP_COMPANYID;

结果:

Oracle高级查询之CONNECT BY的更多相关文章

  1. oracle高级查询(实例基于scott用户四张表)

    oracle高级查询(实例基于scott用户四张表) 分组查询 多表查询 子查询 综合实例 ====================================================== ...

  2. Oracle高级查询之OVER

    注释:为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的 oracel的高级用法:rank()/dense_rank() over(partition by ...orde ...

  3. Oracle 高级查询

    Oracle SQL 一些函数用法 以下sql环境都是在 Oracle 11g/scott完成 Group by 与GROUP BY一起使用的关建字 GROUPING,GROUP SET,ROLLUP ...

  4. Oracle高级查询,over 用法

    注:标题中的红色order by是说明在使用该方法的时候必须要带上order by. 一.rank()/dense_rank() over(partition by ...order by ...) ...

  5. Oracle高级查询、事物、过程及函数

    一.SQL函数 1.分类:单行函数(日期.数值.转换.字符等),多行函数,也称为分组函数(max.min.avg.sum.row_number.rank等). 2.数值函数 abs(n):求数字n的绝 ...

  6. Oracle高级查询,事物,过程及函数

    一 数值函数 数值 abs,ceil,floor,round,trunc字符串 instr,substr SQL>SELECT 'ABS':'|| ABS(-12.3) FROM DUAL; 运 ...

  7. Oracle 高级查询、事物、过程及函数

    一.Sql函数 1.数值函数(输入参数和返回值都是数值型,多数函数精确到38位) --多少次方 ,) from dual; --开方 ) from dual; --绝对值 ) from dual; - ...

  8. Oracle高级查询之over(partition by...)

    现有表,数据如下: eg1:查询年龄第二的队员 通常写法: select * from (select a.*, rownum r from (select t.* from l_student_in ...

  9. oracle高级查询练习题

    1.  列出员工表中每个部门的员工数和部门编号 Select deptno,count(*) from emp group by deptno; 补充1:列出员工表中,员工人数大于3的部门编号和员工人 ...

随机推荐

  1. 基于jQuery点击图像居中放大插件Zoom

    分享一款基于jQuery点击图像居中放大插件Zoom是一款放大的时候会从原图像的位置以动画方式放大到画面中间,支持点击图像或者按ESC键来关闭效果.效果图如下: 在线预览   源码下载 实现的代码. ...

  2. Mybatis generator 自动生成代码(2)

    最近准备开始做一个项目,需要开始手动创建sql,于是将Mybatis generator 工具功能强化了下. 首先,这里引入到版本一点的包 <dependency> <groupId ...

  3. [转]请用fontAwesome代替网页icon小图标

    原文地址:https://www.cnblogs.com/wangfupeng1988/p/4129500.html 1. 引言 网页小图标到处可见,如果一个网页都是干巴巴的文字和图片,而没有小图标, ...

  4. HashTable浅析

    本文转载自: http://rock3.info/blog/2013/12/05/hashtable%E6%B5%85%E6%9E%90/ 一.Hash特点 Hash,就是杂凑算法,Hash(str1 ...

  5. 接口与virtual,override,new关键字

    一,类继承接口 1,首先我们定义一个简单的ITeacher接口,并定义一个Professor类继承它. public interface ITeacher { void Print(); } publ ...

  6. EF code First数据迁移学习笔记

    准备工作 1.新建一个控制台项目, 在"程序包管理控制台"执行 Install-package EntityFramework  //安装EF环境 2.在项目下新建类(Paper) ...

  7. 【IntelliJ IDEA】idea上提交代码到GitHub,已经提交了 但是GitHub上却没有的解决办法

    摘要: 今天提交idea上的代码到GitHub,提交过程已经完成, 在版本控制的Log中可以看到,已经将这一部分都提交更新了    在版本控制的Local Changes中已经看不到提交过的代码了   ...

  8. svn出现skips remain conficted,不能更新代码问题

    出现: skips remain conficted One or more files are in a conflicted state 然后commit的时候出现,很多都已经deleted,但是 ...

  9. java中String new和直接赋值的区别

        Java中String new和直接赋值的区别     对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才 ...

  10. (笔记)Linux下的ioctl()函数详解

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...