树形查询一般用于上下级场合,使用的特殊sql语法包括level,prior,start with,connect by等,下面将就实例来说明其用法。

表定义:

create table tb_hierarchy(
id number(4,0) primary key,
name nvarchar2(20) not null,
pid number(4,0))

充值:

insert into tb_hierarchy(id,name) values('','Gates');
insert into tb_hierarchy(id,pid,name) values('','','Alice');
insert into tb_hierarchy(id,pid,name) values('','','Bill');
insert into tb_hierarchy(id,pid,name) values('','','Cindy');
insert into tb_hierarchy(id,pid,name) values('','','Douglas');
insert into tb_hierarchy(id,pid,name) values('','','Eliot');
insert into tb_hierarchy(id,pid,name) values('','','Mick');
insert into tb_hierarchy(id,pid,name) values('','','Flex');
insert into tb_hierarchy(id,pid,name) values('','','张三');
insert into tb_hierarchy(id,pid,name) values('','','李四');
insert into tb_hierarchy(id,pid,name) values('','','王五');

先让我们查出员工及其上级:

--列出员工和上级
select level,id,name,(prior name) as mngName
from tb_hierarchy
start with pid is NULL
connect by (prior id)=pid

查询结果:

SQL> select level,id,name,(prior name) as mngName
2 from tb_hierarchy
3 start with pid is NULL
4 connect by (prior id)=pid; LEVEL ID NAME MNGNAME
---------- ---------- ---------------------------------------- ----------------------------------------
1 1 Gates
2 2 Alice Gates
3 3 Bill Alice
3 4 Cindy Alice
3 5 Douglas Alice
2 6 Eliot Gates
3 7 Mick Eliot
4 9 张三 Mick
4 10 李四 Mick
4 11 王五 Mick
3 8 Flex Eliot 已选择11行。

从上面的level一列可以看出,Gates居于公司领导核心,属于董事长;他下面是alice,处于总经理地位;Alice下面有三个经理,分别是Bill,Cindy,Douglas...

这些结果是怎么查出来的呢?让我们看看SQL:

select level,id,name,(prior name) as mngName
from tb_hierarchy
start with pid is NULL
connect by (prior id)=pid

解读:

level:属于关键字,是和rownum一样的伪列,代表节点在整棵树中的层级,如Flex处于等级三,他上面有Eliot,Eliot上面有总头头Gates。

prior name:prior属于关键字,代表本条记录的上一条,如本条是(3,8,Flex);那么prior就是(2,6,Eliot);知道了prior是哪一条记录,我们就知道了prior name是Eliot,prior id就是6。

start with:这个语法告诉树形查询应该以pid是空的记录作为树的起点。

下面我们来查查以Mick为起点会是什么效果:

SQL> select level,id,name,(prior name) as mngName
2 from tb_hierarchy
3 start with name='Mick'
4 connect by (prior id)=pid; LEVEL ID NAME MNGNAME
---------- ---------- ---------------------------------------- ----------------------------------------
1 7 Mick
2 9 张三 Mick
2 10 李四 Mick
2 11 王五 Mick

结果查询出了以Mick为组长,张三李四王五为组员的苦逼外包小组。

在国企干活的人一般称底下做事的为员,管员的人为基层干部,上下都是干部的为中层干部,上面再没人的则是首长。

下面我们查查谁是员,谁是基层领导干部,谁是中层领导干部,谁是首长:

SQL> select level,id,name,(prior name) as mngName,
2 decode(level,1,1) as 首长,
3 decode(level,2,1) as 中层干部,
4 decode(level,3,1) as 基层干部,
5 decode(connect_by_isleaf,1,1) as 员工
6 from tb_hierarchy
7 start with pid is NULL
8 connect by (prior id)=pid; LEVEL ID NAME MNGNAME 首长 中层干部 基层干部 员工
---------- ---------- -------------------- -------------------- ---------- ---------- ---------- ----------
1 1 Gates 1
2 2 Alice Gates 1
3 3 Bill Alice 1 1
3 4 Cindy Alice 1 1
3 5 Douglas Alice 1 1
2 6 Eliot Gates 1
3 7 Mick Eliot 1
4 9 张三 Mick 1
4 10 李四 Mick 1
4 11 王五 Mick 1
3 8 Flex Eliot 1 1 已选择11行。

上面的语法中多了一个关键字connect_by_isleaf,它表示当前节点下面没有子节点,或是当前记录下没有地位更低的记录(996!最苦逼的一群人)

下面SQL可以把id前面加点层次:

SQL> select lpad(' ',level,' ')||id AS padid,
2 level,id,name,(prior name) as mngName,
3 decode(level,1,1) as 首长,
4 decode(level,2,1) as 中层干部,
5 decode(level,3,1) as 基层干部,
6 decode(connect_by_isleaf,1,1) as 员工
7 from tb_hierarchy
8 start with pid is NULL
9 connect by (prior id)=pid; PADID LEVEL ID NAME MNGNAME 首长 中层干部 基层干部 员工
---------- ---------- ---------- ---------- -------------------- ---------- ---------- ---------- ----------
1 1 1 Gates 1
2 2 2 Alice Gates 1
3 3 3 Bill Alice 1 1
4 3 4 Cindy Alice 1 1
5 3 5 Douglas Alice 1 1
6 2 6 Eliot Gates 1
7 3 7 Mick Eliot 1
9 4 9 张三 Mick 1
10 4 10 李四 Mick 1
11 4 11 王五 Mick 1
8 3 8 Flex Eliot 1 1 已选择11行。

下面把每个人的上级全列出来:

SQL> col path format a30;
SQL> select level,id,name,(prior name) as mngName,
2 sys_connect_by_path(name,',') as path
3 from tb_hierarchy
4 start with pid is NULL
5 connect by (prior id)=pid; LEVEL ID NAME MNGNAME PATH
---------- ---------- ---------- -------------------- ------------------------------
1 1 Gates ,Gates
2 2 Alice Gates ,Gates,Alice
3 3 Bill Alice ,Gates,Alice,Bill
3 4 Cindy Alice ,Gates,Alice,Cindy
3 5 Douglas Alice ,Gates,Alice,Douglas
2 6 Eliot Gates ,Gates,Eliot
3 7 Mick Eliot ,Gates,Eliot,Mick
4 9 张三 Mick ,Gates,Eliot,Mick,张三
4 10 李四 Mick ,Gates,Eliot,Mick,李四
4 11 王五 Mick ,Gates,Eliot,Mick,王五
3 8 Flex Eliot ,Gates,Eliot,Flex 已选择11行。

--2020年4月18日--

以上用到的全部SQL:

create table tb_hierarchy(
id number(4,0) primary key,
name nvarchar2(20) not null,
pid number(4,0)) insert into tb_hierarchy(id,name) values('','Gates');
insert into tb_hierarchy(id,pid,name) values('','','Alice');
insert into tb_hierarchy(id,pid,name) values('','','Bill');
insert into tb_hierarchy(id,pid,name) values('','','Cindy');
insert into tb_hierarchy(id,pid,name) values('','','Douglas');
insert into tb_hierarchy(id,pid,name) values('','','Eliot');
insert into tb_hierarchy(id,pid,name) values('','','Mick');
insert into tb_hierarchy(id,pid,name) values('','','Flex');
insert into tb_hierarchy(id,pid,name) values('','','张三');
insert into tb_hierarchy(id,pid,name) values('','','李四');
insert into tb_hierarchy(id,pid,name) values('','','王五'); --列出员工和上级
select level,id,name,(prior name) as mngName
from tb_hierarchy
start with pid is NULL
connect by (prior id)=pid --以mick为起点
select level,id,name,(prior name) as mngName
from tb_hierarchy
start with name='Mick'
connect by (prior id)=pid --列出是员,基层干部,中级干部和首长
select level,id,name,(prior name) as mngName,
decode(level,1,1) as 首长,
decode(level,2,1) as 中层干部,
decode(level,3,1) as 基层干部,
decode(connect_by_isleaf,1,1) as 员工
from tb_hierarchy
start with pid is NULL
connect by (prior id)=pid --加入层次列
select lpad(' ',level,' ')||id AS padid,
level,id,name,(prior name) as mngName,
decode(level,1,1) as 首长,
decode(level,2,1) as 中层干部,
decode(level,3,1) as 基层干部,
decode(connect_by_isleaf,1,1) as 员工
from tb_hierarchy
start with pid is NULL
connect by (prior id)=pid --把上级在path里全列出来
select level,id,name,(prior name) as mngName,
sys_connect_by_path(name,',') as path
from tb_hierarchy
start with pid is NULL
connect by (prior id)=pid

Oracle中树形查询使用方法的更多相关文章

  1. ORACLE跨数据库查询的方法

    原文地址:http://blog.csdn.net/huzhenwei/article/details/2533869 本文简述了通过创建database link实现Oracle跨数据库查询的方法 ...

  2. oracle 中对查询出来的数据进行切割、截取等操作

    oracle 中对查询出来的数据进行切割.截取等操作 最近遇到一个问题,需要把一个带有,的字符串拆分成多行.通过查询资料,这个操作需要使用以下2个关键知识: 1. REGEXP_SUBSTR函数 这个 ...

  3. Oracle中如何查询CLOB字段类型的内容

    注:本文来源于:<Oracle中如何查询CLOB字段类型的内容> 语法 select * from table_name where dbms_lob.instr(字段名(clod类型), ...

  4. Oracle中如何查询一个表的所有字段名和数据类型

    Oracle中如何查询一个表的所有字段名和数据类型 查询语法 select A.COLUMN_NAME,A.DATA_TYPE from user_tab_columns A where TABLE_ ...

  5. Oracle中生成uuid的方法

    Oracle中生成uuid的方法 下载LOFTER客户端 在Oracle SQL 提供了一个生成uuid的函数sys_guid: http://download.oracle.com/docs/cd/ ...

  6. Oracle中分页查询语句

    Oracle分页查询语句使我们最常用的语句之一,下面就为您介绍的Oracle分页查询语句的用法,如果您对此方面感兴趣的话,不妨一看. Oracle分页查询语句基本上可以按照本文给出的格式来进行套用.O ...

  7. Oracle 特殊字符模糊查询的方法

    最近在写DAO层的时候,遇到一个问题,就是使用like进行模糊查询时,输入下划线,无法精确查到数据,而是返回所有的数据. 这让我很好奇,百度之后才发现,原来是因为有些特殊字符需要进行转义才可以进行查询 ...

  8. oracle表空间表分区详解及oracle表分区查询使用方法(转+整理)

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  9. 【JOB】Oracle中JOB的创建方法以及一个细节的探究

    在Oracle中可以使用JOB来实现一些任务的自动化执行,类似于UNIX操作系统crontab命令的功能.简单演示一下,供参考. 1.创建表T,包含一个X字段,定义为日期类型,方便后面的定时任务测试. ...

随机推荐

  1. javascript数组笔记

    1.数组 2.利用new创建数组 var arr= new Array(); 3.利用数组字面量创建数组 var 数组名=[]; 4.数组里面的数据叫 5.数组的索引(数组下标从0开始) 6.遍历数组 ...

  2. 《Java核心技术(卷1)》笔记:第12章 并发

    线程 (P 552)多进程和多线程的本质区别:每一个进程都拥有自己的一整套变量,而线程共享数据 (P 555)线程具有6种状态: New(新建):使用new操作符创建线程时 Runnable(可运行) ...

  3. C#LeetCode刷题-拒绝采样

    拒绝采样篇 # 题名   通过率 难度 470 用 Rand7() 实现 Rand10()   34.4% 中等 478 在圆内随机生成点   22.8% 中等

  4. C#算法设计查找篇之02-二分查找

    二分查找(Binary Search) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/699 访问. 二分查找也称折半查 ...

  5. Deep learning-based personality recognition from text posts of online social networks 阅读笔记

    文章目录 一.摘要 二.模型过程 1.文本预处理 1.1 文本切分 1.2 文本统一 2. 基于统计的特征提取 2.1 提取特殊的语言统计特征 2.2 提取基于字典的语言特征 3. 基于深度学习的文本 ...

  6. 如何通过命令行简单的执行C程序

    如何通过命令行简单的执行C语言编写的程序 ​ 首先,我们知道C语言程序都是以xxx.c结尾的,这在Windows系统和Linux系统都是一样的.其次,C程序的执行过程为四步:预处理--编译--汇编-- ...

  7. 提升团队幸福感之:集成 GitLab && JIRA 实现自动化工作流

    佛罗伦萨 - 圣母百花圣殿(图) 前言 GitLab 和 Jira 是平时开发过程中使用非常高频的代码管理系统(开发人员)和项目管理系统(项目管理),通过两套系统的协作完成平常大多数的功能开发,但是两 ...

  8. 9.hbase相关进程作用

    1.协调服务组件Zookeeper Zookeeper的作用如下: 1. 保证任何时候,集群中只有一个HMaster: 2. 存储所有的HRegion的寻址入口: 3. 实时监控HRegionServ ...

  9. 如何选择一台适合Java开发的电脑

    前言 最近在群里有同学求推荐Java开发用的电脑,所以胖哥就出个简单的专题,用我贫瘠的电脑知识来帮助大家选择适合开发的电脑配置.因为家里的主机已经带不动两个 IDEA 了,更别提开个 Docker 啥 ...

  10. 在string.replace中使用具名组匹配

    let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; let re = '2015-01-02'. r ...