使用分析函数实现Oracle 10G提供的CONNECT_BY_ISLEAF和CONNECT_BY_ROOT的功能(转载)
文章转载至:http://blog.csdn.net/wzy0623/article/details/1644049
如果,有侵犯您权益的地方,烦请及时的告知我,我会即刻停止侵权行为
Oracle 10g提供了几个函数:CONNECT_BY_ISLEAF、CONNECT_BY_ROOT、CONNECT_BY_PATH,对树有了更加强大的支持,但是在10g之前,我们没有这些函数,
该如何实现CONNECT_BY_ISLEAF、CONNECT_BY_ROOT这个函数的功能,下面我们介绍下使用分析函数,来解决该问题。
有一个emp表,2个字段,员工id和主管id. 1,emp_id, 2,manager_id
假如有以下资料,一个员工可以对应一个或多个主管id,即一个员工可能有几个主管。
emp_id manager_id
001 101
001 102
101 201
102 202
002 102
003 103
103 203
201 301
203 303
现在要通过任何一个员工id,能查到他的最高主管的id,可能结果不止一笔。
即如果是001,则结果如下:
emp_id manager_id
001 301
001 202
........................
即如果是002,则结果如下:
emp_id manager_id
002 102
........................
即如果是103,则结果如下:
emp_id manager_id
103 303
建表语句:
CREATE TABLE emp
(
emp_id VARCHAR2(10 ),
manager_id VARCHAR2(10 )
);
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
INSERT INTO EMP (EMP_ID, MANAGER_ID) VALUES ('', '');
COMMIT;
在Oracle 10G中可以通过如下语句去实现:
SELECT EMP_ID, MANAGER_ID
FROM (SELECT CONNECT_BY_ROOT(EMP_ID) EMP_ID,
MANAGER_ID,
CONNECT_BY_ISLEAF V_ISLEAF
FROM EMP
CONNECT BY EMP_ID = PRIOR MANAGER_ID)
WHERE V_ISLEAF = 1
这个写法非常简洁,用到了10G connect by 增强的特性,如判断是否叶子节点的伪列 CONNECT_BY_ISLEAF,只使用根行返回结果的一元操作符 CONNECT_BY_ROOT 等,很好。但提问者说使用的是 9i,这就有些麻烦了,能否使用一个 sql 而不是 plsql 实现呢?深入研究后给出了我的 sql:
如下:
SELECT EMP_ID, MANAGER_ID
FROM (SELECT FIRST_VALUE(EMP_ID) OVER(PARTITION BY PART ORDER BY LEV) EMP_ID,
ROW_NUMBER() OVER(PARTITION BY PART ORDER BY LEV DESC) RN,
PART,
MANAGER_ID AS MANAGER_ID
FROM (SELECT EMP_ID, MANAGER_ID, LEVEL LEV, (ROWNUM - LEVEL) PART
FROM EMP
CONNECT BY EMP_ID = PRIOR MANAGER_ID))
WHERE RN = 1;
9i 没有提供 CONNECT_BY_ISLEAF 及 CONNECT_BY_ROOT,但可以使用分析函数实现其基本功能,下面分析一下。
最内层的查询:
SELECT EMP_ID, MANAGER_ID, LEVEL LEV, (ROWNUM - LEVEL) PART
FROM EMP
CONNECT BY EMP_ID = PRIOR MANAGER_ID;
这里用到了从叶子到跟的反向遍历,同时用 (ROWNUM - LEVEL) part 列的值表示一个从叶子到根的路径,为使用分析函数的分区条件做准备。
二层嵌套查询
SELECT FIRST_VALUE(EMP_ID) OVER(PARTITION BY PART ORDER BY LEV) EMP_ID,
ROW_NUMBER() OVER(PARTITION BY PART ORDER BY LEV DESC) RN,
PART,
MANAGER_ID AS MANAGER_ID
FROM (SELECT EMP_ID, MANAGER_ID, LEVEL LEV, (ROWNUM - LEVEL) PART
FROM EMP
CONNECT BY EMP_ID = PRIOR MANAGER_ID);
按 part 分区,以 lev 正排序,再使用 FIRST_VALUE 操作使第一列都显示叶子节点;
按 part 分区,以 lev 倒排序,再使用 ROW_NUMBER () 函数划分等级,等级排第一的即为根节点。
使用分析函数实现Oracle 10G提供的CONNECT_BY_ISLEAF和CONNECT_BY_ROOT的功能(转载)的更多相关文章
- CENTOS 6.4 安装oracle 10g,手工建库及升级到10.2.0.5
一. 数据库软件安装 参照官方手册 1.安装rpm包 注这里的yum直接用163的yum yum -y install binutils compat-libstdc++-33 compat-libs ...
- 未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序解决方案
未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序解决方案 一.现象: C#程序中需要以Provider=OraOLEDB.Oracle.1方式访问ORACLE数据库.但程序执行时报 ...
- oracle 10g 学习之服务器端安装(1)
Oracle 简介 lOracle 是殷墟出土的甲骨文(oracle bone inscriptions)的英文翻译的第一个单词 lOracle 公司是全球最大的信息管理软件及服务供应商,成立于197 ...
- linux centos5.7(32bit) oracle 10g oracle11g
cenOS5.5安装oracle10g(傻瓜篇) http://www.cnblogs.com/fnng/archive/2012/06/19/2554159.html (转) 在cenOS5.5上 ...
- oracle 10G以上版本 树形查询新加的几个功能
1.判断当前节点是否叶子节点 在 Oracle 10g 中,还有其他更多关于层次查询的新特性 .例如,有的时候用户更关心的是每个层次分支中等级最低的内容.那么你就可以利用伪列函数CONNECT_BY_ ...
- oracle 10g
一.安装系统 首先安装Linux系统,根据Oracle官方文档的建议,在机器内存小于1G的情况下,swap分区大小应该设置为内存的2倍大,若内存大于2G则swap分区设置为与内存大小一样. 为防止Or ...
- CentOS 6.3(x86_64)下安装Oracle 10g R2
目 录 一.硬件要求二.软件三.系统安装注意四.安装Oracle前的系统准备工作五.安装Oracle,并进行相关设置六.升级Oracle到patchset 10.2.0.4七.使用rlwrap调用sq ...
- oracle 10g升级到11g
Linux 上Oracle RAC 10g 升级到 Oracle RAC 11g 了解如何在 Oracle Enterprise Linux 5 上逐步将 Oracle RAC 10g 第 2 版升级 ...
- Oracle 10g DataGuard手记之基础配置
DataGuard为企业数据的高可用性,数据安全以及灾难恢复提供支持,一般由一个primary db与几个物理或逻辑standby db组成一个DataGuard配置. 系统环境 操作系统为windo ...
随机推荐
- JavaWeb学习—Servlet
1.什么是Servlet Servlet是一个继承HttpServlet类的Java类 Servlet必须部署在web服务器端,用来处理客户端的请求 2.Servlet运行过程 Web Client ...
- Redis事务和分布式锁
Redis事务 Redis中的事务(transaction)是一组命令的集合.事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行.Redis事务的实现需要用到 MUL ...
- IEnumerable和IEnumerator 详解 【转】
初学C#的时候,老是被IEnumerable.IEnumerator.ICollection等这样的接口弄的糊里糊涂,我觉得有必要切底的弄清楚IEnumerable和IEnumerator的本质. 下 ...
- 微信訪问页面,莫名其妙刷新两次,火狐、谷歌、ie无问题
做微信刮刮卡活动,有个用户刮奖次数的限制,昨天一切正常,所以就修改了一些东西,今天再打开的时候刮奖次数第一次是1,第二次是3,第三次是5.感觉就是页面刷新了两遍. 检查前后台代码.发现一些bug就顺手 ...
- c#常见操作
1. StreamWriter - 文件写入类StreamWriter s = new StreamWriter(address + "/Menu.ini", true);s.Wr ...
- javascript高级知识点——指定上下文实现
代码信息来自于http://ejohn.org/apps/learn/. 当我们将一个对象的点击事件绑定到一个事件触发元素时会发生什么? <ul id="results"&g ...
- gulp简单使用小记
npm install --save-dev 写入package.json里 var gulp = require('gulp'); var less = require('gulp-less ...
- JAVA 类加载器 第14节
JAVA 类加载器 第14节 今天我们将类加载机制5个阶段中的第一个阶段,加载,又叫做装载.为了阅读好区分,以下都叫做装载. 装载的第一步就是要获得二进制的字节流,它可以从读.class文件获得,也可 ...
- java打包/命令行方式运行jar(命令行进行程序测试)
public class Testtmp { public static void main(String[] args) { // TODO Auto-generated method stub f ...
- poj1323--贪心算法
题意:一群人打牌包括你,每人出一张牌,谁最大,谁就算赢一局,问你最少能赢几局? 给出人数N,每人的牌数M,及你的牌. 分析:1.这题需比较大小,就像我们打牌时要将牌排序以便出牌,显然要先将手上的牌进行 ...