oracle 层次查询


语法:
      SELECT ... FROM
           [WHERE condition]                             --过滤某些节点
           [ START WITH [nocycle] start_condition]    --定义查询的起点, 可以使用子查询
          CONNECT BY [[nocycle] PRIOR COLUMN1 = COLUMN2 [AND ...]];   --定义父子关系
          order [ sibilings ] by ...
 
例1:
找出101雇员, 及其全下属/上司
 select *
from myemp
start with employee_id = 101
connect by prior employee_id = manager_id; -- 找下属
-- connect by employee_id = prior manager_id; --找上司
prior在等号哪边,表示哪边是"我的"
找下属:  "我的"employee_id = "别人的"manager_id --> 找出我的下属  (向下查询)
找上司: employee_id = prior manager_id 别人的工号 = 我的经理编号 --> 别人是我的经理 & 别人是我经理的经理 --> 我的上司们
 
注意,level伪列只能和connect by子句结合使用,否则Oracle会返回错误 ORA-01788: 此查询块中要求 CONNECT BY 子句
 
例2:
统计树形的层数
SELECT COUNT(DISTINCT LEVEL)
FROM EMPLOYEES
START WITH MANAGER_ID IS NULL
CONNECT BY PRIOR EMPLOYEE_ID = MANAGER_ID;
例3:
统计树的节点数量 , 例如, 查询每个级别的雇员数量

 select count(level)  --在统计树种节点的数量时, 一定不能加distinct!
from employees
start with manager_id is null
connect by prior employee_id = manager_id
group by level; 
 
例4:
删除子树
delete from myemp
where employee_id in ( select employee_id
from myemp
start with last_name = 'Kochhar'
connect by prior employee_id = manager_id);
 
 

过滤某些结果集


场景1:使用 where 过滤某些节点 , 注意不是过滤分支!

例1:
查看level=2的所有雇员的信息
select level, employee_id, last_name, manager_id
from employees
where level = 2 --注意where子句出现的位置
start with manager_id is null
connect by prior employee_id = manager_id;
 
注意:where子句比connect by后执行。
即先用connect by生成一颗树, 然后再用where来砍树, 并不是where在前面就先执行它
 
例2:
查询Mavris是不是Kochhar的雇员
SELECT *
FROM employees
WHERE last_name = 'Mavris'
START WITH last_name = 'Kochhar' --Kochhar的所有雇员
CONNECT BY PRIOR employee_id = manager_id;
 

场景2: 使用 connect by  ... and ... 过滤某些分支

例1 查询Raphaely及其的所有下属
select *
from employees
start with last_name = 'Raphaely'
connect by prior employee_id = manager_id;
例2 查询除了Raphaely和他下属的所有员工
select *
from employees
start with manager_id is null
connect by prior employee_id = manager_id
and last_name <> 'Raphaely';
 
 

格式化查询  lpad('-', 3 * (level - 1), '-')

例:使用三个横杠作为缩进格式化查询
select *
from employees
start with manager_id is null
connect by prior employee_id = manager_id
and last_name <> 'Raphaely';

 

SYS_CONNECT_BY_PATH() 函数 ☆

作用:
        将父节点到当前节点的路径按照指定的模式展现出来
格式:
        sys_connect_by_path(<列明>,<连接串>)
 
 

CONNECT_BY_ISLEAF 伪列

作用:
        判断层次查询结果集中的行是不是叶子节点
返回值:
        0表示不是叶子节点,
        1表示是叶子节点
 
例:
 

 

CONNECT_BY_ROOT 字段x -> 找到该节点最顶端节点的字段x

用在列名之前,找出此行的根节点行的相同列名的值
不是一直找到"根", 而是一直找到当前便利的分支的

select last_name "Employee",
connect_by_root last_name "Manager",
sys_connect_by_path(last_name, ' -> ') "Path"
from hr.employees
where level > 1
-- start with 加不加??
connect by prior employee_id = manager_id
order by last_name, length("Path");
 

 
思考? 为什么不能加 start with ?  加了会有什么效果?
不加start with , 则每个节点都遍历一次 , connect_by_root 找到顶端的经理人会不同
而加了start with manager_id is null 则从树的根节点 King 开始遍历, 从而connect_by_root每个人的顶端的经理都是King
 
 

10g新特性 采用sibilings排序


作用:
        因为使用order by排序会破坏层次,所以在oracle10g中,增加了siblings关键字的排序给叶子节点的关键字排序
语法:
    order siblings by <expre> asc|desc ; 
它会保护层次,并且在每个等级中按expre排序
注意:
    order siblings by 必须紧跟着connect by
    所以不能再用order by 了
例子:

select t.employee_id,t.manager_id,t.first_name,t.salary,sys_connect_by_path(t.first_name, '->'),level
from hr.employees t
start with manager_id is null
connect by prior employee_id = manager_id
order by salary desc;
 

最后的结果是严格按照salary排序的,这样把层级关系都打乱了
 
采用sibilings排序:
select t.employee_id,
t.manager_id,
t.first_name,
t.salary,
sys_connect_by_path(t.first_name, '->'),
level
from hr.employees t
start with manager_id is null
connect by prior employee_id = manager_id
order siblings by salary desc;

结果的树结构没有被打乱,且没层级的sibilings都是按照salary排序的, 屌屌的~
 
 
 
 
 
 

Oracle 层次查询 connect by的更多相关文章

  1. Oracle层次查询

    Oracle层次查询的语法如下: 下面根据两道“烧脑”的题具体来体现: 1. 根据时间先后顺序,十二星座的英文名称用逗号串起来为'Aries,Taurus,Gemini,Cancer,Leo,Virg ...

  2. 带您了解Oracle层次查询

    http://database.51cto.com/art/201010/231539.htm Oracle层次查询(connect by )是结构化查询中用到的,下面就为您介绍Oracle层次查询的 ...

  3. .Net程序员学用Oracle系列(20):层次查询(CONNECT BY)

    1.层次查询语句 1.1.CONNECT BY 语法 1.2.CONNECT BY 示例 2.层次查询函数 2.1.SYS_CONNECT_BY_PATH 2.2.WMSYS.WM_CONCAT 2. ...

  4. Oracle层次查询start with connect by

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

  5. 【转载】Oracle层次查询和分析函数

    摘要 一组连续的数,去掉中间一些数,如何求出剩下的数的区间(即号段)?知道号段的起止,如何求出该号段内所有的数?知道一个大的号段范围和已经取过的号段,如何求出可用的号段?利用Oracle提供的强大的查 ...

  6. Oracle层次查询和分析函数在号段选取中的应用

    转自:http://www.itpub.net/thread-719692-1-1.html 摘要一组连续的数,去掉中间一些数,如何求出剩下的数的区间(即号段)?知道号段的起止,如何求出该号段内所有的 ...

  7. Oracle - 层次查询

    如果表中含有层次数据,可以通过使用层次查询有序地查看层次数据. 语法: condition:指一个或多个表达式和逻辑(布尔)运算符的组合,并返回TRUE.FALSE或UNKNOWNstart with ...

  8. oracle层次查询的陷阱

    今天开发组同事找到我,说一个简单的层次查询非常慢,业务就是有一个存设备表连接关系的表,从node1连入,从node2连出,现在要找出node2的连出顺序,sql类似于: SELECT LEVEL ID ...

  9. 【转】 oracle 层次查询判断叶子和根节点

    Oracle 9i判断是叶子或根节点,是比较麻烦的一件事情,SQL演示脚本如下: DROP TABLE idb_hierarchical; create TABLE idb_hierarchical ...

随机推荐

  1. PIE SDK栅格矢量化算法

    1.算法功能简介 栅格数据矢量化较为复杂,如果由一幅扫描的数字化地图来建立矢量数据库,则需要经过数字图象处理,如边缘增强.细化.二值化.特征提取及模式识别才能获得矢量数据.人们通常将多色地图分色后逐个 ...

  2. 项目中使用Redis的游标scan的一些小问题

    最近项目中有一个需求就是在下拉中要筛选车辆列表,本来想着是在内存中全部用程序去遍历处理,但发现数据有点多,一个个去处理会有点慢.然后就找到了redis的游标 感觉这个能满足我的需求,我可以把key存成 ...

  3. [转]Java游戏引擎

    JME(jMonkey Engine): JME是一个高性能的3D图形API,采用LWJGL作为底层支持.它的后续版本将支持JOGL.JME和Java 3D具有类似的场景结构,开发者必须以树状方式组织 ...

  4. 设计模式之(十四)责任链模式(Chain of Responsibility)

    在业务场景中,有很多是需要审批的.审核方式还可能常常发生变化,而责任链模式就是为了解决这种场景的情况的. 责任链模式定义:十多个对象都有机会处理请求,从而避免发送者和接受者之间的耦合关系.讲这些对象连 ...

  5. C# DataTable 转实体对象

    DataTable 转实体对象 /// <summary> /// DataTable通过反射获取单个对象 /// </summary> public static T ToS ...

  6. 开源一些C#不常用知识(附上DEMO)

    序:这其实是一个广告贴. 正文:开源一些不常用的C#DEMO,这个是专门写成DEMO的样子,来供大家查阅,当然可以提出意见啥的.或者一些需要加入的DEMO,作者可以添加上. git地址:https:/ ...

  7. IDEA Mac 快捷键

    智能提示 ⌘ -> command ⇧ -> shift ⌥ -> option ⬆ -> 上箭头 ⬇ -> 下箭头 ⌃ -> Control 编辑 快捷键 说明 ...

  8. (原)ubuntu中C++调用libotrch

    转载请注明出处: https://www.cnblogs.com/darkknightzh/p/11479240.html 参考网址: https://pytorch.org/tutorials/ad ...

  9. 判断cms-暴库-后台查找-密码破解

    1.判断网站CMS类型 判断目标 使用工具: 脚本语言 wvs 御剑     domain明小子 操作系统 wwwscan 啊d pangolin(穿山甲) 搭建平台 站长工具 netpark     ...

  10. 树莓派搭建基于flask的web服务器-通过移动端控制LED

    1.概述 在局域网内,基于flask搭建web服务,从而可以使用移动客户端访问该web服务.由于是flask新手,所以本次实现的web服务功能较为简单,即控制LED灯的开/关及闪烁. 2.准备工作 2 ...