语法:

SELECT ... FROM

[WHERE condition]                             --过滤某些节点

       [ START WITH [nocycle] start_condition]    --定义查询的起点, 可以使用子查询

          CONNECT BY [[nocycle] PRIOR COLUMN1 = COLUMN2 [AND ...]];   --定义父子关系

order [ sibilings ] by ...

例1:

找出101雇员, 及其全下属/上司

 select *from myempstart 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 EMPLOYEESSTART WITH MANAGER_ID IS NULL
CONNECT BY PRIOR EMPLOYEE_ID = MANAGER_ID;  

例3:

统计树的节点数量 , 例如, 查询每个级别的雇员数量

 select count(level)  --在统计树种节点的数量时, 一定不能加distinct!from employeesstart with manager_id is null
connect by prior employee_id = manager_idgroup by level;

例4:

删除子树

delete from myempwhere employee_id in ( select employee_idfrom myempstart with last_name = 'Kochhar'connect by prior employee_id = manager_id)

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

例1:

查看level=2的所有雇员的信息

select level, employee_id, last_name, manager_idfrom employeeswhere 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 employeesstart with last_name = 'Raphaely'
connect by prior employee_id = manager_id

例2 查询除了Raphaely和他下属的所有员

select *from employeesstart with manager_id is null
connect by prior employee_id = manager_idand last_name <> 'Raphaely';

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

例:使用三个横杠作为缩进格式化查询

select *from employeesstart with manager_id is null
connect by prior employee_id = manager_idand 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, '->'),levelfrom hr.employees tstart with manager_id is null
connect by prior employee_id = manager_idorder by salary desc;

最后的结果是严格按照salary排序的,这样把层级关系都打乱了

采用sibilings排序:

select t.employee_id,t.manager_id,t.first_name,t.salary,sys_connect_by_path(t.first_name, '->'),levelfrom hr.employees tstart with manager_id is null
connect by prior employee_id = manager_idorder siblings by salary desc; 

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

Oracle的Connect By用法及理解相关推荐

  1. 神通数据库connect by用法

    神通数据库connect by用法 神通数据库大多数sql和Oracle用法一样. 对于connect by ,大致的理解是用于树形结构的表,一般在于查找父子关系数据时使用. 模板sql如下: sel ...

  2. Oracle with语句的用法

    http://database.51cto.com/art/201010/231528.htm Oracle with语句是经常可以见到的语句,下面就为您详细介绍Oracle with语句的用法,如果 ...

  3. Oracle to_char()函数的用法

    Comments - 446 Oracle to_char()函数的用法 The following are number examples for the to_char function. to_ ...

  4. 8、Oracle:group by用法

    第一部分: 来自: http://blog.csdn.net/yanyu529584640/article/details/50616053 首先group by 的简单说明: group by 一般 ...

  5. Oracle数据库之rownum,ORACLE数据库中Rownum用法详解

    ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(,& gt;=,=, ...

  6. Oracle trunc()函数的用法

    --Oracle trunc()函数的用法 /**************日期********************/ 1.select trunc(sysdate) from dual  --20 ...

  7. oracle中类似indexof用法_instr函数

    oracle中类似indexof用法_instr函数 [sql] 在oracle中没有indexof()函数 但是提供了一个 instr() 方法 具体用法: select instr('保定市南市区 ...

  8. Oracle中group by用法

    Oracle中group by用法 在select 语句中可以使用group by 子句将行划分成较小的组,一旦使用分组后select操作的对象变为各个分组后的数据,使用聚组函数返回的是每一个组的汇总 ...

  9. oracle 获得月最后一天,oracle获取本月第一天和最后一天及Oracle trunc()函数的用法...

    select to_char(trunc(add_months(last_day(sysdate), -1) + 1), 'yyyy-mm-dd') "本月第一天", to_cha ...

最新文章

  1. ESXI上的vm虚拟机文件被锁定无法POWER ON的问题处理
  2. linux gcc 链接静态库的几种方式
  3. 德国市占率第一的科沃斯携最新扫地机器人亮相IFA展
  4. c#获取对象的唯一标识_Articy Importer Guide - 01 基本对象处理
  5. DSP 投放的基本流程和算法
  6. vue从入门到精通之基础篇(一)语法概要
  7. plsql打开sql窗口快捷键_SQL干货|为你打开一扇窗—窗口函数
  8. javascript 获取DropDownList选定值的方法
  9. java字节字符流实验报告_Java第09次实验(IO流)--实验报告
  10. dubbo项目引用另一个项目的接口
  11. 写作是最好的学习方法
  12. 计算机科技英语论文,计算机科技英语论文大纲模板 计算机科技英语论文提纲怎么写...
  13. 一份走心的iOS开发规范
  14. 【程序人生】底层程序员,出局
  15. 微信/钉钉电脑端登录后手机端不再提醒
  16. 用JAVA写一个俄罗斯方块游戏tetrisGame
  17. 零知识证明:Sigma协议
  18. 树莓派4B(Ubuntu 22.04 server)与Windows11网线直连(无显示器)
  19. 为什么选择进入金融业?
  20. Android高级进阶--插曲-从Android5.0到Android10各版本变化

热门文章

  1. 用python玩转数据第三周_用Python玩转数据(三)
  2. ASP.NET中的KRE是什么?
  3. fiilt1左耳无法同步_FIIL T1 X真无线运动耳机体验:闪连快充秒同步 媲美AirPods
  4. 为什么你感觉Java难以入门?
  5. 科学计算机解三角函数方程,如何让计算器计算方程如何让fx-82ES的卡西欧计算器解一次,二次,或更高次数方程?是支持三角函数的!...
  6. linux 守护进程小结
  7. 艺赛旗 (RPA) Python 的数据类型
  8. asp.net分页查询
  9. 安装软件和驱动程序需要微软数字签名无法安装?数字签名和数字证书区别
  10. FLV视频转换的利器 - ffmpeg.exe