树结构层次关系即父子关系,类似公司中的部门组织结构树
其中总经理是最大的父节点,下面有助理、市场部、行政办、研发部等子节点,而研发部又细分为研发一部和研发二部;
如hr用户表employees中的employee_id和manager_id。employee_id表示该雇员的编号,manager_id表示领导该雇员的人的编号,即子节点的manager_id值等于父节点的employee_id值。在表的每一行中都有一个表示父节点的manager_id(除根节点外),通过每个节点的父节点,就可以确定整个树结构。
在SELECT命令中使用CONNECT BY 和蔼START WITH 子句可以查询表中的树型结构关系。其命令格式如下:
SELECT 。。。
CONNECT BY {PRIOR 列名1=列名2|列名1=PRIOR 裂名2}
[START WITH];
其中:CONNECT BY子句说明每行数据将是按层次顺序检索,并规定将表中的数据连入树型结构的关系中。PRIORY运算符必须放置在连接关系的两列中某一个的前面。对于节点间的父子关系,PRIOR运算符在的一侧表示父节点,另一侧表示子节点,从而确定查找树结构是的顺序是自顶向下还是自底向上。在连接关系中,除了可以使用列名外,还允许使用列表达式。
START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的根(起始)节点。若该子句被省略,则表示所有满足查询条件的行作为根节点。
START WITH:不但可以指定一个根节点,还可以指定多个根节点。
学习之前,让我们首先对于树结构章节会使用到的关键词有个概念上的认识和理解!
prior:优先的
STARTWITH:指定遍历的起点
CONNECT BY PRIOR:指定遍历的顺序,比如从上到下,从下到上
CONNECT BY NOCYCLE PRIOR:不进行循环遍历,可以避免死循环情况的发生
SYS_CONNECT_BY_PRTH:函数,用于指定层次分隔符
CONNECT_BY_ISLEAF:函数,返回0和1两个值,0代表非末级节点,即下面还有子节点;1代表最末级节点,即下面不再有子节点
据上面的关键字我们来组合一条sql语句:显示employees表中的用户的隶属关系,类似总经理/副总经理/行政办主任/办事员......
我们使用START WITH语句来指定遍历的源头,即从哪里开始,START WITH可以省略,如果省略则表示所有满足查询条件的行作为根节点
CONNECT BY PRIOR用来指定遍历的顺序,等号的两端连接的是父子关系,即是从老子开始找儿子,还是从儿子开始找老子......
e.employee_id=e.manager_id的意思是:首先找到员工的信息,然后再去找上级是这个员工的,这就是从上至下
关于LEVEL:LEVEL需要与CONNECT BY 配合使用,表示树状结构的层级,LEVEL是Oracle保留关键字
--例1:下面的sql语句是上至下进行员工遍历显示,层次结构使用/进行分割
SQL>SELECTLPAD(' ', 2 * LEVEL - 1) || SYS_CONNECT_BY_PATH(e.last_name, '/') AS path
FROMemployees e
STARTWITH e.manager_id IS NULL
CONNECT BY PRIORe.employee_id = e.manager_id
--例2:查找由FORD和BLAKE 领导的所有雇员的信息。
SQL>SELECT EMPNO,ENAME,MGR
FROM EMP
CONNECT BY PRIOR EMPNO=MGR
START WITH ENAME IN(’FORD’,’BLAKE’);
EMPNO ENAME MGR
——————————————————————————
7698 BLAKE 7839
7499 ALLEN 7698
7521 WARD 7698
7654 MARTIN 7698
例3:树结构结果集中不包含Hartstein的树状关系,我们可以这样实现
SQL>SELECTLPAD(' ', 2 * LEVEL - 1) || SYS_CONNECT_BY_PATH(e.last_name, '/') AS path
FROM employees e
START WITHe.manager_id IS NULL
CONNECT BY PRIORe.employee_id = e.manager_id
AND e.last_name <> 'Hartstein'
说明:通过在CONNECT BY 子句后面加AND关键字的方式进行条件筛选