oracle树形结构层级查询之start with ....connect by prior、level、order by以及sys_connect_by_path之浅谈

浅谈oracle树状结构层级查询html

  oracle树状结构查询即层次递归查询,是sql语句常常用到的,在实际开发中组织结构实现及其层次化实现功能也是常常遇到的,虽然我是一个java程序开发者,我一直以为只要精通数据库那么对于java开发你就成功了三分之一,本篇中主要介绍start with...connect by prior 、order by 、sys_connect_by_pathjava

  概要:树状结构一般由根节点、父节点、子节点和叶节点组成,简单来讲,一张表中存在两个字段,dept_id,par_dept_id,那么经过找到每一条记录的父级id便可造成一个树状结构,也就是par_dept_id(子)=dept_id(父),通俗的说就是这条记录的par_dept_id是另一条记录也就是父级的dept_id,其树状结构层级查询的基本语法是:面试

  SELECT [LEVEL],*sql

  FEOM table_name 数据库

  START WITH 条件1oracle

  CONNECT BY PRIOR 条件2函数

  WHERE 条件3学习

  ORDER BY 排序字段测试

  说明:LEVEL---伪列,用于表示树的层次优化

     条件1---根节点的限定条件,固然也能够放宽权限,以得到多个根节点,也就是获取多个树

     条件2---链接条件,目的就是给出父子之间的关系是什么,根据这个关系进行递归查询

     条件3---过滤条件,对全部返回的记录进行过滤。

     排序字段---对全部返回记录进行排序

  对prior说明:要的时候有两种写法:connect by prior dept_id=par_dept_idconnect by dept_id=prior par_dept_id,前一种写法表示采用自上而下的搜索方式(先找父节点而后找子节点),后一种写法表示采用自下而上的搜索方式(先找叶子节点而后找父节点)。 

  树状结构层次化查询须要对树结构的每个节点进行访问而且不能重复,其访问步骤为:

  

  大体意思就是扫描整个树结构的过程即遍历树的过程,其用语言描述就是:

  步骤一:从根节点开始;

  步骤二:访问该节点;

  步骤三:判断该节点有无未被访问的子节点,如有,则转向它最左侧的未被访问的子节,并执行第二步,不然执行第四步; 

  步骤四:若该节点为根节点,则访问完毕,不然执行第五步; 

  步骤五:返回到该节点的父节点,并执行第三步骤。 

  除此以外,sys_connect_by_path函数是和connect  by 一块儿使用的,在实战中具体带目的具体介绍!

  实战:最近作项目的组织结构,对于部门的各级层次显示,因为这部分掌握不牢固,用最笨的like模糊查询解决了,虽然功能实现了,可是问题不少,如扩展性很差,稍微改下需求就要进行大改,不满意最后对其进行了优化。在开发中能用数据库解决的就不要用java去解决,这也是我一直保持的想法并坚持着。

  对于建表语句及其测试数据我放在另一篇博客中,须要进行测试的能够过去拷贝运行测试验证下!

  博客地址浅谈oracle树状结构层级查询测试数据

  在这张表中有三个字段:dept_id 部门主键id;dept_name  部门名称;dept_code 部门编码;par_dept_id   父级部门id(首级部门为 -1);

  1. 当前节点遍历子节点(遍历当前部门下全部子部门包括自己)
    select t.dept_id, t.dept_name, t.dept_code, t.par_dept_id, level 
    from SYS_DEPT t 
    start with t.dept_id = '40288ac45a3c1e8b015a3c28b4ae01d6' 
    connect by prior t.dept_id = t.par_dept_id 
    order by level, t.dept_code

    结果:

    dept_id=40288ac45a3c1e8b015a3c28b4ae01d6 是客运部主键,对其下的全部子部门进行遍历,同时用  order by level,dept_code 进行排序 以便达到实际生活中想要的数据;共31条数据,部分数据如图所示:


    可是:

      有问题啊,若是你想在上面的数据中获取层级在2也就是level=2的全部部门,发现刚开始的时候介绍的语言不起做用?而且会报ORA-00933:sql命令未正确结束,why?

    这个我暂时也没有获得研究出理论知识,可是改变下where level='2'的位置发现才会能够的。错误的和正确的sql咱们对比一下,之后会用就行,要是路过的大神知道为何,还请告知下,万分感谢!

    错误sql:

    select t.dept_id, t.dept_name, t.dept_code, t.par_dept_id, level 
    from SYS_DEPT t  
    start with t.dept_id = '40288ac45a3c1e8b015a3c28b4ae01d6' 
    connect by prior t.dept_id = t.par_dept_id 
    where level = '2' 
    order by level, t.dept_code
    正确sql:
    select t.dept_id, t.dept_name, t.dept_code, t.par_dept_id, level  
    from SYS_DEPT t 
    where level = '2' 
    start with t.dept_id = '40288ac45a3c1e8b015a3c28b4ae01d6' 
    connect by prior t.dept_id = t.par_dept_id 
    order by level, t.dept_code 


    固然了,这个对其余形式的where过滤全部返回记录没有影响的,这个只是一个例外!

  2. sys_connect_by_path函数求父节点到子节点路径
    简单介绍下,在oracle中sys_connect_by_path与connect by 一块儿使用,也就是先要有或创建一棵树,不然无用还会报错。它的主要做用体如今path上即路径,是能够吧一个父节点下的全部节点经过某个字符区分,而后连接在一个列中显示。
    sys_connect_by_path(column,clear),其中column是字符型或能自动转换成字符型的列名,它的主要目的就是将父节点到当前节点的“path”按照指定的模式出现,char能够是单字符也能够是多字符,但不能使用列值中包含的字符,并且这个参数必须是常量,且不容许使用绑定变量,clear不要用逗号
    文字容易让人疲劳,放图和代码吧!

    select sys_connect_by_path(t.dept_name,'-->'),t.dept_id, t.dept_name, t.dept_code, t.par_dept_id, level  
    from SYS_DEPT t   
    start with t.dept_id = '40288ac45a3c1e8b015a3c28b4ae01d6'  
    connect by prior t.dept_id = t.par_dept_id 
    order by level, t.dept_code 

    结果:

     
    结束语
    一个坑两周时间填平,最近终于休息闲了下来,整理整理加深记忆,好记性不如烂笔头,不要高估本身的记性,许久不用很快就会忘记的,在学习的道路上,但愿本身也但愿各位路过的同行不要放弃学习,任重而道远!如今的我很菜,之后我会成为大神!哈哈,意淫一下!
    爱人是路,朋友是树,人生有一条路,一条路上有许多树,有钱的时候别迷路,缺钱的时候靠靠树,幸福的时候莫忘路,休息的时候浇浇树。
    开心一乐
    惊弓之鸟——说的是去面试的刚毕业大学生,一听到用人单位提到行业经验就落荒而逃的事情;
    上联:作 I T 风风雨雨 又一年下联:卖电脑 辛辛苦苦 每一天横批:从小不学好,长大卖电脑!

相关文章
相关标签/搜索