Oracle 层级查询(Hierarchical Queries)

2024-03-12 01:12

本文主要是介绍Oracle 层级查询(Hierarchical Queries),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果一张表中的数据存在分级(即数据间存在父子关系),利用普通SQL语句显示数据间的层级关系非常复杂,可能需要多次连接才能完整的展示出完成的层级关系,更困难的是你可能不知道数据到底有多少层。而利用Oracle的层级查询,则可以很方便的显示出层级。

一、语法简介

层级关系定义语法如由start withconnect by两个子句构成:

start withconnect by [nocycle] [prior] …
或
connect by [nocycle] [prior]start with
  • start with …,定义根节点,即层级关系的起点
  • connect by …,定义层级关系,即上下级的连接条件
  • prior,层级关系中指定父级列
  • nocycle,当层级关系出现循环时依然输出结果,和connect_by_iscycle配合使用

相关伪列/函数/排序:

  • level,显示当前记录所在的层级,根节点的层级为1,下级为2,依次类推
  • sys_connect_by_path,显示指定列的完整层级关系,可以自定义连接符
  • connect_by_isleaf,判断当前记录是否叶子节点(没有子孙节点)
  • connect_by_iscycle,和nocycle配合使用,判断层级关系是否存在循环
  • connect_by_root …,显示当前记录的根节点相关信息
  • order siblings by …,按照层级依次排序,即先按层级1排序,再按层级2排序,依次类推

二、应用示例

我们以Oracle Sample Schema中的hr.employees表来演示。这张雇员表中的记录通过2个字段定义上下级关系,employee_id为雇员编号,manager_id为上级的雇员编号,例如King的employee_id为100,他的manager_id是空(没有上级),Kochhar的manager_id是100,代表他的上级是King:

select last_name, employee_id, manager_id from employees;

在这里插入图片描述

2.1 基本层级查询

下面的SQL查询每位雇员的层级,同时用通过伪列evel显示出来:

select last_name, employee_id, manager_id,level
from employees
start with employee_id=100 connect by manager_id=prior employee_id;

在这里插入图片描述

  • start with employee_id=100,定义根节点,这里代表从King开始计算层级
  • level 伪列显示当前记录的层级,根节点King的Level为1,Kochhar为King的下级,level为2
  • connect by 定义层级关系,这里是通过manager_id和employee_id的关系判断层级
  • prior 指示层级关系中谁是父级列,虽然我们从列名的含义可以判断出manager_id对应上级记录的employee_id,但是Oracle并不知道,我们需要用prior关键字指示,即manager_id(本级记录)=prior employee_id(上级记录);

上面的示例,如果倒过来查层级关系,将employee_id为110的雇员(层级为4)作为根节点,那么prior关键字也需要换位置:

select last_name, employee_id, manager_id,level
from employees
start with employee_id=110 connect by  prior manager_id=employee_id;

在这里插入图片描述

2.2 显示完整层级关系

通过函数sys_connect_by_path可以显示完整的层级路径,该函数有2个参数,列和连接符号。示例中还使用了ltrim函数去除了最左边的连接符:

select last_name, employee_id, manager_id, level, 
ltrim(sys_connect_by_path(last_name, ' => '),' => ') Hierarchy
from employees
start with employee_id=101 connect by manager_id=prior employee_id; 

在这里插入图片描述

2.3 显示是否存在循环

Kochhar对应的上级employee_id为100,如果修改成206,那么层级关系就出现了循环(子孙节点同时也是自己的祖先节点),当出现循环时,普通的层级查询会出现下列报错:
在这里插入图片描述
这时可以使用nocycle关键字,指示即使出现循环依然返回结果,并通过connect_by_iscycle伪列显示哪些记录出现了循环:

select last_name, employee_id, manager_id, level, ltrim(sys_connect_by_path(last_name, ' => '),' => ') Hierarchy, 
connect_by_iscycle 是否循环
from employees
start with employee_id=101 connect by nocycle manager_id=prior employee_id;

在这里插入图片描述

2.4 判断是否为叶子节点

connect_by_isleaf伪列可以显示当前记录是否为叶子节点,如果是叶子节点则返回1,否则返回0。例如用where connect_by_isleaf=1可以过滤出所有的叶子节点:

select last_name, employee_id, manager_id, level, connect_by_isleaf
from employees
-- where connect_by_isleaf =1
start with employee_id=101 connect by manager_id=prior employee_id; 

在这里插入图片描述

2.5 显示层级的根节点

connect_by_root后面跟上列名,可以显示该列层级的根节点:

select last_name, employee_id, manager_id, level, 
ltrim(sys_connect_by_path(last_name, ' => '),' => ') Hierarchy,
connect_by_root last_name Leader
from employees
where level>1 
connect by manager_id=prior employee_id; 

在这里插入图片描述

2.6 按层级排序

在层级查询中,如果要按照层级关系排序,普通的order by语句是无法做到的,此时需要使用order siblings by语句,该语句会按照层级依次对结果进行排序(先按层级1排序,再按层级2排序…):

select last_name, employee_id, manager_id, level, ltrim(sys_connect_by_path(last_name, ' => '),' => ') Hierarchy
from employees
start with employee_id=100 connect by manager_id=prior employee_id
order siblings by last_name;

在这里插入图片描述

这篇关于Oracle 层级查询(Hierarchical Queries)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/799686

相关文章

Oracle登录时忘记用户名或密码该如何解决

《Oracle登录时忘记用户名或密码该如何解决》:本文主要介绍如何在Oracle12c中忘记用户名和密码时找回或重置用户账户信息,文中通过代码介绍的非常详细,对同样遇到这个问题的同学具有一定的参... 目录一、忘记账户:二、忘记密码:三、详细情况情况 1:1.1. 登录到数据库1.2. 查看当前用户信息1.

mysql线上查询之前要性能调优的技巧及示例

《mysql线上查询之前要性能调优的技巧及示例》文章介绍了查询优化的几种方法,包括使用索引、避免不必要的列和行、有效的JOIN策略、子查询和派生表的优化、查询提示和优化器提示等,这些方法可以帮助提高数... 目录避免不必要的列和行使用有效的JOIN策略使用子查询和派生表时要小心使用查询提示和优化器提示其他常

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

PLsql Oracle 下载安装图文过程详解

《PLsqlOracle下载安装图文过程详解》PL/SQLDeveloper是一款用于开发Oracle数据库的集成开发环境,可以通过官网下载安装配置,并通过配置tnsnames.ora文件及环境变... 目录一、PL/SQL Developer 简介二、PL/SQL Developer 安装及配置详解1.下

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

查询SQL Server数据库服务器IP地址的多种有效方法

《查询SQLServer数据库服务器IP地址的多种有效方法》作为数据库管理员或开发人员,了解如何查询SQLServer数据库服务器的IP地址是一项重要技能,本文将介绍几种简单而有效的方法,帮助你轻松... 目录使用T-SQL查询方法1:使用系统函数方法2:使用系统视图使用SQL Server Configu

oracle如何连接登陆SYS账号

《oracle如何连接登陆SYS账号》在Navicat12中连接Oracle11g的SYS用户时,如果设置了新密码但连接失败,可能是因为需要以SYSDBA或SYSOPER角色连接,解决方法是确保在连接... 目录oracle连接登陆NmOtMSYS账号工具问题解决SYS用户总结oracle连接登陆SYS账号

Oracle数据库如何切换登录用户(system和sys)

《Oracle数据库如何切换登录用户(system和sys)》文章介绍了如何使用SQL*Plus工具登录Oracle数据库的system用户,包括打开登录入口、输入用户名和口令、以及切换到sys用户的... 目录打开登录入口登录system用户总结打开登录入口win+R打开运行对话框,输php入:sqlp

MYSQL关联关系查询方式

《MYSQL关联关系查询方式》文章详细介绍了MySQL中如何使用内连接和左外连接进行表的关联查询,并展示了如何选择列和使用别名,文章还提供了一些关于查询优化的建议,并鼓励读者参考和支持脚本之家... 目录mysql关联关系查询关联关系查询这个查询做了以下几件事MySQL自关联查询总结MYSQL关联关系查询