当前位置: 首页 > news >正文

ORACLE查询树型关系start with connect by prior

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

在oracle中的select语句可以用start with...connect by prior子句实现递归查询。其基本语法是:

select LEVEL,t.* from tablename t
where cond3
start with cond1
connect by cond2; 

注意:这里的where条件是放在tablename后面,如果放在cond2后面,执行查询报sql命令未正确结束的错误。

cond1:是根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。 

cond2:是连接限定条件,格式为“PRIOR 列名1=列名2” 或 “列名1=PRIOR 列名2”。其中用prior表示上一条记录,比如connect by prior id=parentid就是说上一条记录的ID是本条记录的parentid,即本记录的父亲是上一条记录。 

cond3:是结果过滤条件,用于对返回的所有记录进行过滤(即在树查询出来后再进行过滤)。 

简单说来是将一个树状结构存储在一张表里,比如一个表中存在两个字段: id,parent_id
那么可以通过该查询表示每一条记录的parent是谁,就可以形成一个树状结构。 

1、关于start with
START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的起始节点。若该子句被省略,则表示所有满足查询条件的行作为起始节点。不但可以指定一个起始节点,还可以指定多个起始节点。

2、 关于 PRIOR
在自顶向下查询树结构时,不但可以从根节点开始,还可以定义任何节点为起始节点,以此开始向下查找。这样查找的结果就是以该节点为开始的结构树的一枝。运算符 PRIOR 被放置于等号前后的位置,决定着查询时的检索顺序。
PRIOR 被置于 CONNECT BY 子句中等号的前面时,则强制从根节点到叶节点的顺序检索,即由父节点向子节点方向通过树结构,我们称之为自顶向下的方式。如:
CONNECT BY PRIOR EMPNO=MGR
PIROR 运算符被置于 CONNECT BY 子句中等号的后面时,则强制从叶节点到根节点的顺序检索,即由子节点向父节点方向通过树结构,我们称之为自底向上 的方式。例如:
CONNECT BY EMPNO=PRIOR MGR
在这种方式中也应指定一个开始的节点。

3、使用LEVEL
在具有树结构的表中,每一行数据都是树结构中的一个节点,由于节点所处的层次位置不同,所以每行记录都可以有一个层号。层号根据节点与根节点的距离确定。不论从哪个节点开始,该起始节点的层号始终为1 ,起始节点的子节点为2,依此类推。

4、节点和分支的裁剪
在对树结构进行查询时,可以去掉表中的某些行,也可以剪掉树中的一个分支,使用WHERE子句来限定树型结构中的单个节点,以去掉树中的单个节点,但它却不影响其后代节点(自顶向下检索时)或前辈节点(自底向顶检索时)。

5、排序显示
像在其它查询中一样,在树结构查询中也可以使用ORDER BY子句,改变查询结果的显示顺序,而不必按照遍历树结构的顺序。
--------------------------------------------------------------------------------

分割线

--------------------------------------------------------------------------------

上面简单介绍了oracle树结构查询语法,下面说明下实际应用中,因重复数据导致的特殊情况
 场景:一张表test_table中存储每个核心系统source,且每个source有自己专业机构id,每个专业机构下有相应的下级机构。但各个核心间的机构id存在重复。表数据如表1所示。

表1

idparent_idsource
2011核心1
1 核心1
20108201核心1
20108201核心2
2012核心2
2 核心2


表2

idparent_idsource
20108201核心1
2011核心1
1 核心1
2012核心2
2 核心2
20108201核心2
2011核心1
1 核心1
2012核心2
2 核心2

表3

idparent_idsource
20108201核心1
2011核心1
1 核心1
2011核心1
1 核心1

实际数据为核心1有专业机构为id=1,二级机构为id=201,三级机构为id=20108;核心2有专业机构为id=2,二级机构为id=201,三级机构为id=20108。

如果在不知道表内具体数据的情况下,直接使用以下语句从三级机构id=20108遍历查询其根节点,结果如表2所示。导致该原因是20108存在重复,201也存在重复,分别关联递归出多个树结构。

select * from test_table t
start with t.id = '20108'
connect by t.id = prior t.parent_id;

如果此时加上where条件,只查询核心系统1的三极机构id=20108对应的机构树结构。效果如表3所示。很明显where条件只是在表2的基础上进行再次筛选而已,结果不是我们想要的三级层次树结构。

select * from test_table t
where t.source = '核心1'
start with t.id = '20108'
connect by t.id = prior t.parent_id;

解决因不同核心数据重复导致关联出多个树结构问题,只需将限定条件加在start with和connect by上即可。具体SQL如下,效果详见表4。

select * from test_table t
start with (t.id = '20108' and t.source = '核心1')
connect by (t.id = prior t.parent_id and t.source = '核心1');

表4

idparent_idsource
20108201核心1
2011核心1
1 核心1

 

转载于:https://my.oschina.net/u/163737/blog/1475461

相关文章:

  • CentOS7安装Python3
  • 漂亮的css
  • 文件操作
  • fetch 从初识到应用
  • oreo自适应图标
  • 容器服务--如何在阿里云容器服务上运行基于TensorFlow的Alexnet
  • centos6.x完全禁用IPv6的方法
  • 细说地方门户网站运营的六大经验
  • 列表常用方法
  • 点击按钮,删除数组-对象中的数据
  • 【Spark】RDD操作具体解释4——Action算子
  • DevOps、敏捷开发、云计算,三剑客的小时代
  • 相对和绝对路径及命令cd、mkdir、rmdir、rm
  • 命令+mybatis-generator插件自己主动生成Mapper映射文件
  • Shell笔记4——if条件语句的知识和实践
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Fastjson的基本使用方法大全
  • go append函数以及写入
  • Java程序员幽默爆笑锦集
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • ng6--错误信息小结(持续更新)
  • python3 使用 asyncio 代替线程
  • windows下如何用phpstorm同步测试服务器
  • 多线程 start 和 run 方法到底有什么区别?
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 基于webpack 的 vue 多页架构
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 消息队列系列二(IOT中消息队列的应用)
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • ​HTTP与HTTPS:网络通信的安全卫士
  • #Linux(帮助手册)
  • (07)Hive——窗口函数详解
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • .“空心村”成因分析及解决对策122344
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .net Signalr 使用笔记
  • .NET 表达式计算:Expression Evaluator
  • .NET 发展历程
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .net和php怎么连接,php和apache之间如何连接
  • .NET开发者必备的11款免费工具
  • /3GB和/USERVA开关
  • ::before和::after 常见的用法
  • @Autowired 与@Resource的区别
  • []C/C++读取串口接收到的数据程序
  • [BZOJ3757] 苹果树
  • [C# 开发技巧]实现属于自己的截图工具
  • [C#]手把手教你打造Socket的TCP通讯连接(一)
  • [C++] sqlite3_get_table 的使用
  • [CSS]文字旁边的竖线以及布局知识