树形查询一般用于上下级场合,使用的特殊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. 8、Builder 建造者模式 组装复杂的实例 创造型模式

    1.什么是Builder模式 定义: 将一个复杂对象的构建与表示相分离,使得同样的构建过程可以创建不同的表示.大白话就是,你不需要知道这个类的内部是什么样的,只用把想使用的参数传进去就可以了,达到了解 ...

  2. Django中manage.py migrate无效的问题

    在改变Django-model中结构后,makemigrations可以识别到改变但migrate没有操作,数据库中表结构也没有改变,原因如下: 在由Django-model自动生成的数据库表中有名为 ...

  3. C#LeetCode刷题之#110-平衡二叉树(Balanced Binary Tree)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4074 访问. 给定一个二叉树,判断它是否是高度平衡的二叉树. 本 ...

  4. SpringBoot实现本地存储文件上传及提供HTTP访问服务

    笔者计划为大家介绍分布式文件系统,用于存储应用的图片.word.excel.pdf等文件.在开始介绍分布式文件系统之前,为大家介绍一下使用本机存储来存放文件资源. 二者的核心实现过程是一样的: 上传文 ...

  5. Vulnhub篇Photographerr

    0x00 靶机信息 靶机:Photographerr:1 难度:中 下载:https://www.vulnhub.com/entry/photographer-1,519/ 0x01 信息收集 靶场网 ...

  6. python设计模式之命令模式

    python设计模式之命令模式 现在多数应用都有撤销操作.虽然难以想象,但在很多年里,任何软件中确实都不存在撤销操作.撤销操作是在1974年引入的,但Fortran和Lisp分别早在1957年和195 ...

  7. Elasticsearch第五篇:PlainElastic.Net 操作 Elasticsearch

    再次强调,我安装的Elasticsearch 版本是 7.8.0 ,C# 操作 Elasticsearch 的驱动有 NEST.Elasticsearch.net .PlainElastic.Net ...

  8. 【NOI2015】荷马史诗 - 哈夫曼树

    题目描述 追逐影子的人,自己就是影子 ——荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛&g ...

  9. IOS 如何持久化自定义对象 2014-08-01 01:38

    如果持久话自定义对象 那么这个对象一定要遵循 NSCoding 协议 并实现编解码:然后再将编解码后的数据 NSKeyedArchiver 到NSData中   @interface NSKeyAnd ...

  10. .net Core 下使用 X509Certificate2 给报文加签

    起因 项目开发中途出现需求需要对接其他公司接口,使用证书进行认证传输,之前在.Net下搞过但是都是对方给我证书 这次需要我生成公钥/私钥,公钥给他这样操作. 生成私钥/公钥(这里是RSA算法,长度规定 ...