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

浅谈oracle树状结构层级查询

原文地址:浅谈oracle树状结构层级查询

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

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

SELECT [LEVEL],*

FEOM table_name

START WITH 条件1

CONNECT BY PRIOR 条件2

WHERE 条件3

ORDER BY 排序字段

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

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

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

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

排序字段---对所有返回记录进行排序

对prior说明:要的时候有两种写法:connect by prior dept_id=par_dept_id或connect 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);

当前节点遍历子节点(遍历当前部门下所有子部门包括本身)

5selectt.dept_id, t.dept_name, t.dept_code, t.par_dept_id,level

fromSYS_DEPT t

startwitht.dept_id ='40288ac45a3c1e8b015a3c28b4ae01d6'

connectbypriort.dept_id = t.par_dept_id

orderbylevel, t.dept_code

结果:

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

但是:

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

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

错误sql:

6selectt.dept_id, t.dept_name, t.dept_code, t.par_dept_id,level

fromSYS_DEPT t

startwitht.dept_id ='40288ac45a3c1e8b015a3c28b4ae01d6'

connectbypriort.dept_id = t.par_dept_id

wherelevel='2'

orderbylevel, t.dept_code

正确sql:

6selectt.dept_id, t.dept_name, t.dept_code, t.par_dept_id,level

fromSYS_DEPT t

wherelevel='2'

startwitht.dept_id ='40288ac45a3c1e8b015a3c28b4ae01d6'

connectbypriort.dept_id = t.par_dept_id

orderbylevel, t.dept_code

当然了,这个对其他形式的where过滤所有返回记录没有影响的,这个只是一个例外!

sys_connect_by_path函数求父节点到子节点路径

简单介绍下,在oracle中sys_connect_by_path与connect by 一起使用,也就是先要有或建立一棵树,否则无用还会报错。它的主要作用体现在path上即路径,是可以吧一个父节点下的所有节点通过某个字符区分,然后链接在一个列中显示。

sys_connect_by_path(column,clear),其中column是字符型或能自动转换成字符型的列名,它的主要目的就是将父节点到当前节点的“path”按照指定的模式出现,char可以是单字符也可以是多字符,但不能使用列值中包含的字符,而且这个参数必须是常量,且不允许使用绑定变量,clear不要用逗号。

文字容易让人疲劳,放图和代码吧!

5selectsys_connect_by_path(t.dept_name,'-->'),t.dept_id, t.dept_name, t.dept_code, t.par_dept_id,level

fromSYS_DEPT t

startwitht.dept_id ='40288ac45a3c1e8b015a3c28b4ae01d6'

connectbypriort.dept_id = t.par_dept_id

orderbylevel, t.dept_code

结果:

结束语

一个坑两周时间填平,最近终于休息闲了下来,整理整理加深记忆,好记性不如烂笔头,不要高估自己的记性,许久不用很快就会忘记的,在学习的道路上,希望自己也希望各位路过的同行不要放弃学习,任重而道远!现在的我很菜,以后我会成为大神!哈哈,意淫一下!

爱人是路,朋友是树,人生有一条路,一条路上有许多树,有钱的时候别迷路,缺钱的时候靠靠树,幸福的时候莫忘路,休息的时候浇浇树。

开心一乐

惊弓之鸟——说的是去面试的刚毕业大学生,一听到用人单位提到行业经验就落荒而逃的事情;

上联:做 I T 风风雨雨 又一年

下联:卖电脑 辛辛苦苦 每一天

横批:从小不学好,长大卖电脑!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 几分钟 电影 几分钟 热泪 几秒钟 心动
    翔于阅读 203评论 0 1
  • 你不用像刺猬一样活着,会刺痛别人,也会刺痛自己。 成为小太阳,暖别人的心,也暖到自己的心
    不爱种胡萝的兔子阅读 254评论 0 0
  • 9:38pm 岁月还是太长了 和人生一样 一个人的时候就占了一生的九成 反正我是这样 也可以说 无聊的时候太多了 ...
    五月和第三天阅读 141评论 1 2
  • 香格里拉的传说太多,广而闻名的有独克宗古城、普达措公园、梅里雪山等,但很少人知道香格里拉还有个纳帕海 —— 一个被...
    有盏茶阅读 1,495评论 18 19