有层次结构的菜单树,后台库表结构通常会设计为B-tree结构,

就是菜单节点上有一个PID字段,记录自己的父节点号,

通过这种自关联的方式隐含树的层次结构,如:

CREATE TABLE T_MENU(
ID    NUMBER,  -- 节点号
-- NAME  VARCHAR2(50),
PID   NUMBER DEFAULT 0  -- 父节点号。0为根节点,不存在id=0的节点
);INSERT INTO T_MENU (ID, PID) VALUES ('1', '0');
INSERT INTO T_MENU (ID, PID) VALUES ('2', '1');
INSERT INTO T_MENU (ID, PID) VALUES ('3', '1');
INSERT INTO T_MENU (ID, PID) VALUES ('4', '2');
INSERT INTO T_MENU (ID, PID) VALUES ('5', '2');
INSERT INTO T_MENU (ID, PID) VALUES ('6', '3');
INSERT INTO T_MENU (ID, PID) VALUES ('7', '3');
INSERT INTO T_MENU (ID, PID) VALUES ('8', '5');
INSERT INTO T_MENU (ID, PID) VALUES ('9', '5');
INSERT INTO T_MENU (ID, PID) VALUES ('10', '7');
INSERT INTO T_MENU (ID, PID) VALUES ('11', '7');
INSERT INTO T_MENU (ID, PID) VALUES ('12', '10');
INSERT INTO T_MENU (ID, PID) VALUES ('13', '10');SELECT * FROM T_MENU T ORDER BY T.ID ASC;

上面初始化的数据,其树形结构如下:

这种结构的菜单数据,该如何查询呢,通常来说,我们会有两种查询场景:

  • 给出父节点号,查询它下边的所有子孙节点;

  • 给出子节点号,查询它在菜单树中的位置。

这两个查询,可通过SQL的 start with ... connect by prior 递归查询法查询

向下遍历,给出父节点ID=7, 查询它的所有子节点

SELECT T.ID, T.PID, LEVELFROM T_MENU TSTART WITH T.PID = '7'
CONNECT BY PRIOR T.ID = T.PIDORDER BY LEVEL ASC;

查询结果如下:

ID PID LEVEL
10 7 1
11 7 1
12 10 2
13 10

2

向上遍历,给出节点ID=7, 查询它的所有父节点序列

SELECT T.ID, T.PID, LEVELFROM T_MENU TSTART WITH T.ID = '7'
CONNECT BY T.ID = PRIOR T.PIDORDER BY LEVEL DESC;

查询结果如下:

ID PID LEVEL
1 0 3
3 1 2
7 3 1

SQL解释

START WITH 子句: 这是遍历的起始条件,也是遍历结果中第一层(LEVEL = 1)的数据条件。CONNECT BY PRIOR 子句: 这是表自关联的连接条件,PRIOR字段是已有数据行的字段,用它与表中其它行的非PRIOR字段进行关联。CONNECT BY 后边可以有多个条件,每个条件都可以有或没有PRIOR关键字.

自关联递归是如何进行的呢?根据START WITH 条件找到起始记录后,在起始记录中取PRIOR字段的值,然后在本表中查询这样的数据行:它的非PRIOR字段值与起始记录的PRIOR字段值 之间的关系,符合CONNECT BY 条件.

以上面例子中的向下遍历为例,具体地,先根据起始条件找到PID = '7'的记录,有两条,分别是ID = 10 和 ID = 11,这是查询的起始记录,也就是第一层.然后连接条件是

PRIOR T.ID = T.PID 

那是说要查找PID = 起始记录的ID值(即10和11) 的数据,没有PID = 11的记录,PID = 10的记录有两条,即ID 为12 和13 的记录,这就是查询结果的第二层,以此类推,以第二层记录为起始记录,查找PID=12或13的记录,为第三层,这里没有第三层数据,递归结束.

相关写法

在Oracle中有一种与此等效的写法,就是使用WITH AS 语句递归查询,这种写法显式地进行了递归自关联查询,其查询过程与上面语法十分相似,可以通过分析这种写法来理解上面的语法含义.

下面把上述例子中的向上遍历SQL,改写为WITH AS 递归写法:

WITH TMP(ID, PID) AS(SELECT T.ID, T.PIDFROM T_MENU TWHERE T.ID = '7'UNION ALLSELECT B.ID, B.PIDFROM TMP A, T_MENU BWHERE A.PID = B.ID)
SELECT M.ID, M.PID, ROWNUM FROM TMP M ORDER BY ROWNUM DESC;

转载于:https://www.cnblogs.com/LinuSiyu/p/7940845.html

B-tree结构菜单的递归查询相关推荐

  1. Mysql 索引 总结 —— 概述 || 索引优势劣势|| 索引结构(索引是在MySQL的存储引擎层中实现的)|| BTREE 结构||B+TREE 结构||MySQL中的B+Tree||索引分类

    索引概述 MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构(有序). 在数据之外,数据库系统还维护者满足特定查找算法的数据结构, 这些数据结构以某种方式引用(指向 ...

  2. DWZ中Tree树形菜单的treeCheck如何获取返回值解决方案

    最近在对DWZ和asp.net MVC3进行整合,其中遇到了很多问题,总算一一解决了,今天就说说题目所示的问题解决方案. 想做一个基于角色的权限管理,要对每一个Action进行权限控制.就想用DWZ的 ...

  3. 分级显示HTML,SSM框架下,以tree结构分级显示数据

    1.在Controller层建立跳转tree.jsp以及获取tree数据的方法: @ApiOperation(value = "树") @RequestMapping(value ...

  4. 【vue js】省市区js数据转为tree结构

    使用: //引入 import { addressToTree } from '@/utils/area';data(){return {// 地区数据areaOptions:addressToTre ...

  5. mysql cte递归_SQLSERVER中CTE语句结构及CTE递归查询

    SQL SERVER中CTE语句结构及CTE递归查询 CTE语句结构 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语 ...

  6. vue 递归组件多级_Vue递归组件实现树形结构菜单

    Tree 组件是递归类组件的典型代表,它常用于文件夹.组织架构.生物分类.国家地区等等,世间万物的大多数结构都是树形结构.使用树控件可以完整展现其中的层级关系,并具有展开收起选择等交互功能. 如图所示 ...

  7. oracle树状结构递归,Oracle:递归查询(树形结构数据)

    Oracle树形结构数据-相关知识总结 Oracle树形结构数据--基本知识 1.数据组成 2.基本查询 2.1.查询某节点及该节点下的所有子孙节点 SELECT   *      FROM QIAN ...

  8. 如何利用 C# 实现 K-D Tree 结构?

    我的朋友海伦一直使用在线约会网站寻找适合自己的约会对象.尽管约会网站会推荐不同的人选,但她没有从中找到喜欢的人.经过一番总结,她发现曾交往过三种类型的人: 不喜欢的人 魅力一般的人 极具魅力的人 尽管 ...

  9. tree结构穿梭 vue_结合el-tree和el-transfer搞一个树形穿梭框

    最近遇到个需求,穿梭框中的内容是树形结构的数据.查看elementUI的transfer组件是不支持树形结构的数据,也就不能直接使用了.但是el-tree组件支持啊,那如果让tree组件和transf ...

最新文章

  1. 机洗内裤容易得暗病?这个锅我们袜子不背!
  2. myeclipse查看mysql里面_myeclipse查询数据库
  3. 8953n的user获取权限以及remount
  4. jquery mobile开发笔记之Ajax提交数据
  5. mysql union join_MySQL 超新手入门(5) JOIN 与 UNION 查询
  6. myeclipse + tomcat 项目自动部署
  7. 一加nfc门禁卡录入_忘记门禁卡不再徘徊 一加7T多功能NFC过来拯救你
  8. mysql插入数据到底哪里错了?
  9. 老司机整理对Nginx性能优化
  10. vue h5微信公众号网页(总结)
  11. css linux 等宽字体,css 等宽字体有哪些
  12. 《剑来》语句摘录(四)
  13. GP数列 三角形斜边 小码哥的生日 完全平方数
  14. 第一次使用公有云需要注意啥
  15. python-函数参数和文档
  16. 微信视频号头像怎么换?怎么设置?必看!5个思路帮你快速敲定头像
  17. [C#] DataView用法
  18. 【爬虫】9行python下载王者荣耀所有英雄的高清壁纸(附代码和图片下载)
  19. Java TCP实现高仿版QQ聊天(一)
  20. 常见问题及解决方法1

热门文章

  1. Codeforces Round #309 (Div. 2) C
  2. JDBC:Java世界中的ODBC
  3. 12cR2 RAC+RAC+ADG ORA-16854
  4. Python链接Mssql之Python库pymssql
  5. 黑客发飙!智能汽车不太安全你还敢开?
  6. java的观察者模式
  7. Tomcat启动 java.lang.OutOfMemoryError
  8. apache 日志切割
  9. rpm包安装mysql5.6
  10. 近场通讯技术 (1)