B-tree结构菜单的递归查询
有层次结构的菜单树,后台库表结构通常会设计为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结构菜单的递归查询相关推荐
- Mysql 索引 总结 —— 概述 || 索引优势劣势|| 索引结构(索引是在MySQL的存储引擎层中实现的)|| BTREE 结构||B+TREE 结构||MySQL中的B+Tree||索引分类
索引概述 MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构(有序). 在数据之外,数据库系统还维护者满足特定查找算法的数据结构, 这些数据结构以某种方式引用(指向 ...
- DWZ中Tree树形菜单的treeCheck如何获取返回值解决方案
最近在对DWZ和asp.net MVC3进行整合,其中遇到了很多问题,总算一一解决了,今天就说说题目所示的问题解决方案. 想做一个基于角色的权限管理,要对每一个Action进行权限控制.就想用DWZ的 ...
- 分级显示HTML,SSM框架下,以tree结构分级显示数据
1.在Controller层建立跳转tree.jsp以及获取tree数据的方法: @ApiOperation(value = "树") @RequestMapping(value ...
- 【vue js】省市区js数据转为tree结构
使用: //引入 import { addressToTree } from '@/utils/area';data(){return {// 地区数据areaOptions:addressToTre ...
- mysql cte递归_SQLSERVER中CTE语句结构及CTE递归查询
SQL SERVER中CTE语句结构及CTE递归查询 CTE语句结构 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语 ...
- vue 递归组件多级_Vue递归组件实现树形结构菜单
Tree 组件是递归类组件的典型代表,它常用于文件夹.组织架构.生物分类.国家地区等等,世间万物的大多数结构都是树形结构.使用树控件可以完整展现其中的层级关系,并具有展开收起选择等交互功能. 如图所示 ...
- oracle树状结构递归,Oracle:递归查询(树形结构数据)
Oracle树形结构数据-相关知识总结 Oracle树形结构数据--基本知识 1.数据组成 2.基本查询 2.1.查询某节点及该节点下的所有子孙节点 SELECT * FROM QIAN ...
- 如何利用 C# 实现 K-D Tree 结构?
我的朋友海伦一直使用在线约会网站寻找适合自己的约会对象.尽管约会网站会推荐不同的人选,但她没有从中找到喜欢的人.经过一番总结,她发现曾交往过三种类型的人: 不喜欢的人 魅力一般的人 极具魅力的人 尽管 ...
- tree结构穿梭 vue_结合el-tree和el-transfer搞一个树形穿梭框
最近遇到个需求,穿梭框中的内容是树形结构的数据.查看elementUI的transfer组件是不支持树形结构的数据,也就不能直接使用了.但是el-tree组件支持啊,那如果让tree组件和transf ...
最新文章
- 机洗内裤容易得暗病?这个锅我们袜子不背!
- myeclipse查看mysql里面_myeclipse查询数据库
- 8953n的user获取权限以及remount
- jquery mobile开发笔记之Ajax提交数据
- mysql union join_MySQL 超新手入门(5) JOIN 与 UNION 查询
- myeclipse + tomcat 项目自动部署
- 一加nfc门禁卡录入_忘记门禁卡不再徘徊 一加7T多功能NFC过来拯救你
- mysql插入数据到底哪里错了?
- 老司机整理对Nginx性能优化
- vue h5微信公众号网页(总结)
- css linux 等宽字体,css 等宽字体有哪些
- 《剑来》语句摘录(四)
- GP数列 三角形斜边 小码哥的生日 完全平方数
- 第一次使用公有云需要注意啥
- python-函数参数和文档
- 微信视频号头像怎么换?怎么设置?必看!5个思路帮你快速敲定头像
- [C#] DataView用法
- 【爬虫】9行python下载王者荣耀所有英雄的高清壁纸(附代码和图片下载)
- Java TCP实现高仿版QQ聊天(一)
- 常见问题及解决方法1