准备测试数据

with department as (
	SELECT '61515' as id, '1001' as dep_no, '部门1' as dep_name, '1' as dep_level, '0' as parent_dep, '1' as dep_order from dual
	UNION
	SELECT '14562', '1002', '部门2', '1', '0', '2' from dual
	UNION
	SELECT '41364', '1003', '部门3', '1', '0', '3' from dual
	UNION
	SELECT '74156', '100101', '部门1-1', '2', '1001', '1' from dual
	UNION
	SELECT '21456', '100102', '部门1-2', '2','1001', '2' from dual
	UNION
	SELECT '62149', '100103', '部门1-3', '2','1001', '3' from dual
	UNION
	SELECT '31546', '100201', '部门2-1', '2','1002', '1' from dual
	UNION
	SELECT '14635', '10010101', '部门1-1-1', '3','100101', '1' from dual
)

上面的临时表中简单存储了部门的信息,其中每个部门都存储了一个父级部门编号,dep_level是当前部门所处的层级,例如"部门1"处于1级部门,它的父级部门编号是0,也就是没有父级部门

sql层级查询

SELECT
	*
FROM
department
CONNECT BY PRIOR dep_no = parent_dep

以上sql代码可将部门关系分层级查询出来,结果如下

可以看到,这条语句将部门以及部门下的子部门按顺序显示了出来,但是如何理解CONNECT BY PRIOR dep_no = parent_dep呢

对CONNECT BY PRIOR的理解

CONNECT BY PRIOR dep_no = parent_dep可理解为将每一条数据,也就是每一个部门作为根节点,并且根据dep_no = parent_dep的条件向下生长,图示如下:

这是其中一个跟节点——部门1的层级情况,所有部门查询的结果并列排序,具体排列顺序取决于排序条件,没有排序条件以数据库的自然顺序排序。

指定根节点

SELECT
	*
FROM
department
CONNECT BY PRIOR dep_no = parent_dep
start with dep_no = '1001'

start with指定根节点,若不指定,所有数据均为根节点。

如果将sql改为如下写法,将会得到一个逆向生长的层级树

SELECT
	*
FROM
department
CONNECT BY dep_no = PRIOR parent_dep
-- 或者 CONNECT BY PRIOR parent_dep = dep_no
start with dep_no = '10010101'

排序方式

上面查询所有数据的结果显然不满足每一级部门顺序排序

我们想得到一级部门顺序排序,并且二级部门在一级部门下顺序排序,以此类推...

如果我们直接加上order by会打乱原本的层级结构

应该使用SIBLINGS关键字

SELECT
	*
FROM
department
CONNECT BY PRIOR dep_no = parent_dep
start with parent_dep = '0' -- 指定一级部门为根节点
ORDER SIBLINGS BY dep_order;

至此,得到了最终的顺序层级结构

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐