Oracle高级查询之CONNECT BY
为了方便大家学习和测试,所有的例子都是在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语句如下:
- select *
- from scott.emp e
- start with e.ename = 'KING'
- connect by prior e.empno = e.mgr;
我们再来看另外一个实例,反过来查询'SMITH'的所有上司。SQL语句如下:
- select *
- from scott.emp e
- start with e.ename = 'SMITH'
- connect by e.empno = prior e.mgr;
通过上面的两个实例,估计大家应该理解的差不多了,接下来介绍connect by的几个固定搭档。
1、sys_connect_by_path函数
语法:sys_connect_by_path(列名, '分隔符')。
作用:从start with的地方开始遍历,将遍历到的路径根据函数中的分隔符,组成一个新的字符串。
- select sys_connect_by_path(ename, '/') ename_tree
- from scott.emp
- start with ename = 'KING'
- connect by mgr = prior empno;
插个题外话,介绍sys_connect_by_path函数使用的一个小技巧,把查询行转换成列,把表emp的所有列名以'|'分隔开输出(提示:大家可以把下面的语句拆开来逐个分析),SQL语句如下:
- select max(ltrim(sys_connect_by_path(column_name, '|'), '|')) column_names
- from (select column_name, rownum rnum
- from user_tab_columns
- where table_name = 'EMP')
- start with rnum = 1
- connect by rnum = rownum;
2、level:在结构化查询结果中,每一行都是结构中的一个节点,level表示该节点在结构中的层次,根节点为1,根节点的子节点为2,以此类推。
下面SQL语句很直观的展示效果:
- select ename, sys_connect_by_path(ename, '/') ename_tree, level
- from scott.emp
- start with ename = 'KING'
- connect by mgr = prior empno;
3、connect_by_root:用在列名之前,返回当前节点的根节点对应列的值。connect_by_isleaf:返回当前节点是否为叶子节点,“是”返回1,“否”返回0。
下面SQL语句很直观的展示效果:
- select sys_connect_by_path(ename, '/') ename_tree,
- connect_by_root ename as root,
- connect_by_isleaf as isleaf
- from scott.emp e
- start with e.ename = 'KING'
- connect by prior e.empno = e.mgr;
创建表,初始化数据;
- CREATE TABLE TB_COMPANY
- (
- COMPANY_ID INTEGER PRIMARY KEY,
- COMPANY VARCHAR2(256),
- UP_COMPANYID INTEGER
- );
- INSERT INTO TB_COMPANY VALUES (0, '总公司', NULL);
- INSERT INTO TB_COMPANY VALUES (1, '北京分公司', 0);
- INSERT INTO TB_COMPANY VALUES (2, '上海分公司', 0);
- INSERT INTO TB_COMPANY VALUES (3, '海淀区分部', 1);
- INSERT INTO TB_COMPANY VALUES (4, '东城区分部', 1);
- INSERT INTO TB_COMPANY VALUES (5, '黄埔区分部', 2);
- INSERT INTO TB_COMPANY VALUES (6, '静安区分部', 2);
- COMMIT;
全部数据:
递归查询SQL:
- SELECT (RPAD(' ', 2*(LEVEL-1), '-' ) || COMPANY) COMPANY_NAME, CONNECT_BY_ROOT COMPANY, CONNECT_BY_ISLEAF, LEVEL , SYS_CONNECT_BY_PATH(COMPANY, '/')
- FROM TB_COMPANY
- START WITH UP_COMPANYID IS NULL
- CONNECT BY PRIOR COMPANY_ID = UP_COMPANYID;
结果:
说明:
1. CONNECT_BY_ROOT 返回当前节点的最顶端节点
2. CONNECT_BY_ISLEAF 判断是否为叶子节点,如果这个节点下面有子节点,则不为叶子节点
3. LEVEL 伪列表示节点深度
4. SYS_CONNECT_BY_PATH函数显示详细路径,并用“/”分隔
递归查询SQL:
- SELECT * FROM TB_COMPANY START WITH COMPANY_ID = 1 CONNECT BY PRIOR COMPANY_ID = UP_COMPANYID;
结果:
Oracle高级查询之CONNECT BY的更多相关文章
- oracle高级查询(实例基于scott用户四张表)
oracle高级查询(实例基于scott用户四张表) 分组查询 多表查询 子查询 综合实例 ====================================================== ...
- Oracle高级查询之OVER
注释:为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的 oracel的高级用法:rank()/dense_rank() over(partition by ...orde ...
- Oracle 高级查询
Oracle SQL 一些函数用法 以下sql环境都是在 Oracle 11g/scott完成 Group by 与GROUP BY一起使用的关建字 GROUPING,GROUP SET,ROLLUP ...
- Oracle高级查询,over 用法
注:标题中的红色order by是说明在使用该方法的时候必须要带上order by. 一.rank()/dense_rank() over(partition by ...order by ...) ...
- Oracle高级查询、事物、过程及函数
一.SQL函数 1.分类:单行函数(日期.数值.转换.字符等),多行函数,也称为分组函数(max.min.avg.sum.row_number.rank等). 2.数值函数 abs(n):求数字n的绝 ...
- Oracle高级查询,事物,过程及函数
一 数值函数 数值 abs,ceil,floor,round,trunc字符串 instr,substr SQL>SELECT 'ABS':'|| ABS(-12.3) FROM DUAL; 运 ...
- Oracle 高级查询、事物、过程及函数
一.Sql函数 1.数值函数(输入参数和返回值都是数值型,多数函数精确到38位) --多少次方 ,) from dual; --开方 ) from dual; --绝对值 ) from dual; - ...
- Oracle高级查询之over(partition by...)
现有表,数据如下: eg1:查询年龄第二的队员 通常写法: select * from (select a.*, rownum r from (select t.* from l_student_in ...
- oracle高级查询练习题
1. 列出员工表中每个部门的员工数和部门编号 Select deptno,count(*) from emp group by deptno; 补充1:列出员工表中,员工人数大于3的部门编号和员工人 ...
随机推荐
- ISO8601时间格式
格式解析 R2/2015-06-04T19:25:16.828696-07:00/P1DT10S 上面的字符串通过"/"分为了三部分即: 重复次数/开始时间/运行间隔 重复次数 R ...
- python 文件 IO 操作
Python 的底层操作 * 其实Python的文件IO操作方法,和Linux底层的差不多 打开 f = open(filename , "r") 后面的 "r" ...
- netty tcp拆包
private List<byte[]> getCompletePacket(byte[] bytes, ByteBuf byteBuf) { byte[] clone = bytes.c ...
- Android——开机启动功能(Service和BroadcastReceiver)
BroadcastReceiver(广播接收器):发出广播让服务器去接收 BootReceiver.java package com.example.chenshuai.test321; import ...
- javascript 60行编写的俄罗斯方块游戏
转自 http://***/share/1759652641295360.htm <!doctype html><html><head></head>& ...
- SQL SERVER 事务和锁
内容皆整理自网络 一.事务 作者:郭无心链接:https://www.zhihu.com/question/31346392/answer/59815366来源:知乎著作权归作者所有.商业转载请联系作 ...
- hazelcast初探
Hazelcast作为一个高度可扩展的数据分发和集群平台,提供了高效的.可扩展的分布式数据存储.数据缓存.Hazelcast是开源的,在分布式技术方面,Hazelcast提供了十分友好的接口供开发者选 ...
- python转义符的使用
写了几行代码不能用.========有个需要的注意的就是在pycharm中看见蓝色字体要注意了一定是关键字什么,这个以后要注意. import os # g = os.walk("D:\aa ...
- 【html】param 以及 embed 的有关 flash 属性详解
本文主要介绍 param 和 embed 标签中有关 flash 的一些属性及其属性值. 首先我们需要知道 param 和 embed 标签是单独出现的,而不是成对出现的,下面的代码是一般 flash ...
- Java设计模式(18)策略模式(Strategy模式)
Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...