平时工作中出报表时,要求分别列出员工的一级部门,二级部门....,在数据库中,部门表(unit)的设计一般为在表中维护每个部门的上级部门(pid字段),或者通过一个关联表(unit_link)维护层级关系(uid:部门表中的主键,pid:上级部门的id,这种可以解决一对多的关系)。

之前取各级部门时用到了很多子查询很麻烦,现在考虑了一个做法,用到了connect by,sys_connect_by_path(9i以后)。

sql语句如下,可以创建视图使用,只需改变临时表,可获得各节点的信息:

--开始--

/*with tmp as
(select b.objno,
b.objname,
sys_connect_by_path(b.objno, '>') objnos,
sys_connect_by_path(b.objname, '>') objnames
from budgetdept b
start with b.id in ('30461F609D0AB57BE050007F01004203',
'30461F609D09B57BE050007F01004203')
connect by prior b.id = b.pid)*/

with tmp as
(select u.id,u.objname,
sys_connect_by_path(u.id, '>') objnos,
sys_connect_by_path(u.objname, '>') objnames
from orgunit u, orgunitlink k
where u.isdelete = 0
and u.id = k.oid
start with u.id = '402881e70ad1d990010ad1e5ec930008'
connect by prior k.oid = k.pid)
select substr(t.objnos,
instr(t.objnos, '>', 1, 1) + 1,
case
when instr(t.objnos, '>', 1, 2) > 0 then
instr(t.objnos, '>', 1, 2) - instr(t.objnos, '>', 1, 1) - 1
else
length(t.objnos) - instr(t.objnos, '>', 1, 1)
end) objno1,

substr(t.objnames,
instr(t.objnames, '>', 1, 1) + 1,
case
when instr(t.objnames, '>', 1, 2) > 0 then
instr(t.objnames, '>', 1, 2) - instr(t.objnames, '>', 1, 1) - 1
else
length(t.objnames) - instr(t.objnames, '>', 1, 1)
end) objname1,
substr(t.objnos,
case
when instr(t.objnos, '>', 1, 2) > 0 then
instr(t.objnos, '>', 1, 2) + 1
else
999
end,
case
when instr(t.objnos, '>', 1, 3) > 0 then
instr(t.objnos, '>', 1, 3) - instr(t.objnos, '>', 1, 2) - 1
else
length(t.objnos) - instr(t.objnos, '>', 1, 2)
end) objno2,
substr(t.objnames,
case
when instr(t.objnames, '>', 1, 2) > 0 then
instr(t.objnames, '>', 1, 2) + 1
else
999
end,
case
when instr(t.objnames, '>', 1, 3) > 0 then
instr(t.objnames, '>', 1, 3) - instr(t.objnames, '>', 1, 2) - 1
else
length(t.objnames) - instr(t.objnames, '>', 1, 2)
end) objname2,
substr(t.objnos,
case
when instr(t.objnos, '>', 1, 4) > 0 then
instr(t.objnos, '>', 1, 4) + 1
else
999
end,
case
when instr(t.objnos, '>', 1, 4) > 0 then
instr(t.objnos, '>', 1, 4) - instr(t.objnos, '>', 1, 3) - 1
else
length(t.objnos) - instr(t.objnos, '>', 1, 3)
end) objno3,
substr(t.objnames,
case
when instr(t.objnames, '>', 1, 4) > 0 then
instr(t.objnames, '>', 1, 4) + 1
else
999
end,
case
when instr(t.objnames, '>', 1, 4) > 0 then
instr(t.objnames, '>', 1, 4) - instr(t.objnames, '>', 1, 3) - 1
else
length(t.objnames) - instr(t.objnames, '>', 1, 3)
end) objname3,
substr(t.objnos,
case
when instr(t.objnos, '>', 1, 4) > 0 then
instr(t.objnos, '>', 1, 4) + 1
else
999
end,
case
when instr(t.objnos, '>', 1, 5) > 0 then
instr(t.objnos, '>', 1, 5) - instr(t.objnos, '>', 1, 4) - 1
else
length(t.objnos) - instr(t.objnos, '>', 1, 4)
end) objno4,
substr(t.objnames,
case
when instr(t.objnames, '>', 1, 4) > 0 then
instr(t.objnames, '>', 1, 4) + 1
else
999
end,
case
when instr(t.objnames, '>', 1, 5) > 0 then
instr(t.objnames, '>', 1, 5) - instr(t.objnames, '>', 1, 4) - 1
else
length(t.objnames) - instr(t.objnames, '>', 1, 4)
end) objname4,
substr(t.objnos,
case
when instr(t.objnos, '>', 1, 5) > 0 then
instr(t.objnos, '>', 1, 5) + 1
else
999
end,
case
when instr(t.objnos, '>', 1, 6) > 0 then
instr(t.objnos, '>', 1, 6) - instr(t.objnos, '>', 1, 5) - 1
else
length(t.objnos) - instr(t.objnos, '>', 1, 5)
end) objno5,
substr(t.objnames,
case
when instr(t.objnames, '>', 1, 5) > 0 then
instr(t.objnames, '>', 1, 5) + 1
else
999
end,
case
when instr(t.objnames, '>', 1, 6) > 0 then
instr(t.objnames, '>', 1, 6) - instr(t.objnames, '>', 1, 5) - 1
else
length(t.objnames) - instr(t.objnames, '>', 1, 5)
end) objname5,
t.*
from tmp t;

--结束--

思路是这样的:通过connect by与sys_connect_by_path获取到部门路径的字符串,通过分割符(>)去截取。

例如:       objno                 objname                         objnos                             objnames

D001                    凤凰网                           >D001                              >凤凰网

D002                    信息部                       >D001>D002                    >凤凰网>信息部

D003                    研发组       >D001>D002>D003    >凤凰网>信息部>研发组 

根据instr(objnos,'>',1,X)获取分割符的位置(instr(objnos,'>',1,X)登录0时说明后面不包含此字符了,返回0,会出现截取不正确的字符串,赋值999,从第999个字符开始截取,一般就会截取空字符串了),使用substr去截取,从而获得各层级的数据。

结果:

   一级编号   一级名称         二级编号    二级名称         三级编号     三级名称          四级编号     四级部门          五级编号      五级名称     当前编号   当前名称

   D001      凤凰网                                                                                                                                                        D001       凤凰网

D001      凤凰网             D002       信息部                                                                                                                        D002       信息部

D001      凤凰网             D002       信息部            D003         研发组                                                                                   D003       研发组

目前只想到了这种方法

ORACLE-树状数据结构获取各层级节点信息的更多相关文章

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

    浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...

  2. 浅谈oracle树状结构层级查询测试数据

    浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...

  3. 小程序插件使用wx.createSelectorQuery()获取不到节点信息

    发现小程序一个bug, 在小程序插件中使用wx.createSelectorQuery()获取不到节点信息,需要在后面加入in(this) 例如: const query = wx.createSel ...

  4. uni-app——小程序插件使用wx.createSelectorQuery()获取不到节点信息

    发现小程序一个bug, 在小程序插件中使用wx.createSelectorQuery()获取不到节点信息,需要在后面加入in(this) 例如: const query = wx.createSel ...

  5. C# 递归构造树状数据结构(泛型),如何构造?如何查询?

    十年河东,十年河西,莫欺少年穷. 学无止境,精益求精 难得有清闲的一上午,索性写篇博客. 首先,我们需要准备一张表,如下范例: create table TreeTable ( TreeId ) no ...

  6. oracle 树状查询

    做树状查询的时候,oracle有自己的优势,一条sql语句就可以搞定,而mysql这种数据库就只能用递归了... 递归的项目实例: //递归取到栏目路径 public List getTreeList ...

  7. oracle 树状结构递归 PL/SQL输出控制 包括空格输出控制

    树状结构 存储过程中通过递归构建,类似BBS回帖显示,代码共三段: 建表,插入数据,创建存储过程显示: 1.create table article(id number primary key,con ...

  8. 树 List Leaves 【用数组模拟了树状结构建树+搜索叶子节点+按照特殊规律输出每个叶子节点】

    Given a tree, you are supposed to list all the leaves in the order of top down, and left to right. I ...

  9. C#树状图 初始默认选中节点

    效果图: <script type="text/javascript"> $(document).ready(function () { GetTree(); GetG ...

随机推荐

  1. TP复习11

    ## ThinkPHP 3.1.2 模板中的基本语法#讲师:赵桐正微博:http://weibo.com/zhaotongzheng 本节课大纲:一.导入CSS和JS文件 1.css link js ...

  2. iOS开发——数据持久化Swift篇&(三)SQLite3

    SQLite3 使用 //******************** 5.3 SQLite3存储和读取数据 func use_SQLite3() { //声明一个Documents下的路径 var db ...

  3. CSS 居中大全【转】

    我看最近微博流行 CSS 居中技术,老外码农争相写相关的文章,一篇赛一篇的长啊,我把几篇归纳总结了一下,算是笔记. 孔乙己曾说:“茴香豆的回字有四种写法”,万一哪天有个面试官问你:“居中一共有几种写法 ...

  4. IOS文件存储小结

    转自:http://tyragain.lofter.com/post/84706_c1503 首选项设置存储 NSUserDefaults 以及通过它控制的SettingBundle  NSUserD ...

  5. 教程:如何减小iOS应用程序的大小?

    本文译自:Reducing the size of my App Q: 怎样才能让我的程序安装包小一点,让程序的下载和安装更快速? A: 本文收集了一些减小程序安装包大小的相关技巧(当第一次下载和安装 ...

  6. apache htaccess

    #RewriteCond :重新条件#RewriteRule : 重写规则# .htaccess文件中的规则会以它们出现的顺序被处理 <IfModule mod_rewrite.c>Rew ...

  7. WPF 之 线程使用

    但凡涉及到图形界面,往往的设计都是不支持或者不推荐使用多个线程操作界面内容.而且通常会有一个专门的线程调度器来处理任务线程和界面线程的问题. 下面提供两个方案: 1.使用Dispatcher.Begi ...

  8. C# mvc--EF引用程序集 和EDMX中相关的文件说明

  9. [Javascript] 面向对象编程思想

    1.创建对象 1.1 new 用new进行创建对象: var user = new Object(); user.age = 12;//同时为对象添加属性 user.name = 'ajun'; 1. ...

  10. [ASP.Net]TableLayoutPanel的使用

    以前都是使用Panel.没有用过其他容器类.郁闷,要控制界面的自适应真是麻烦.平常用一用dock.anchor差不多了,但是,更复杂的情景下,就没法了.例如一行有多个控件,有的要求跟据窗口缩放,只缩放 ...