Mysql8和Oracle实际项目中递归查询树形结构
背景:
项目升级,引入MySQL数据库,之前一直用的是Oracle数据,在做用户登录单位维护的时候,需要返回该用户所属单位下的所有子单位。下边是模拟项目数据实践的过程。
数据准备:
准备一张单位表,里面存储下级单位以及上级单位的对应关系数据。
-- 创建单位表
CREATE TABLE UNITS (ID INT PRIMARY KEY,NAME VARCHAR(255),PARENT_ID INT
);-- 插入数据
INSERT INTO UNITS (ID, NAME, PARENT_ID)
VALUES(1500, '1500单位', NULL),(1501, '1501单位', 1500),(15011, '15011单位', 1501),(15012, '15012单位', 1501),(150121, '150121单位', 15012),(1600, '1600单位', NULL),(1601, '1601单位', 1600),(1602, '1602单位', 1600);
实践:
1、Oracle做法
主要使用START WITH
和CONNECT BY PRIOR
完成递归查询,多用于层次查询。
START WITH
:表示递归的起始记录。
CONNECT BY PRIOR
:表示递归时与当前记录的关联关系,其中PRIOR
的位置是是可以变动的,位置的不同,其查询结果也不同。
所有顶级单位向下查询属于该单位的所有的子单位:
# 使用START WITH和CONNECT BY PRIOR完成递归查询,以所有PARENT_ID IS NULL的记录为起始记录,关联表中的ID字段,查询所有属于下级单位
SELECT * FROM UNITS U CONNECT BY PRIOR ID = PARENT_ID START WITH PARENT_ID IS NULL;ID |NAME |PARENT_ID|
------|--------|---------|1500|1500单位 | |1501|1501单位 | 1500|15011|15011单位 | 1501|15012|15012单位 | 1501|
150121|150121单位| 15012|1600|1600单位 | |1601|1601单位 | 1600|1602|1602单位 | 1600|
根据指定单位向下查询属于该单位的所有的子单位:
# 指定查询1600单位下的所有的子单位,注意向下查找,PRIOR的位置在ID的前边
SELECT * FROM UNITS U CONNECT BY PRIOR ID = PARENT_ID START WITH PARENT_ID = 1600;ID |NAME |PARENT_ID|
----|------|---------|
1601|1601单位| 1600|
1602|1602单位| 1600|
根据子单位向上查询属于该单位的所有的上级单位,如果不要包含指定的子单位,那就在结果集中过滤掉即可:
# 查询1501的所有的上级单位,注意向上查找,PRIOR的位置在PARENT_ID的前边
SELECT * FROM UNITS U CONNECT BY ID = PRIOR PARENT_ID START WITH ID = 1501;ID |NAME |PARENT_ID|
----|------|---------|
1501|1501单位| 1500|
1500|1500单位| |
2、Mysql做法
主要是使用关键WITH RECURSIVE
进行递归查询,不过要求,Mysql的版本需要在8.0以上。
所有顶级单位向下查询属于该单位的所有的子单位:
# WITH RECURSIVE是MySQL8支持的递归关键字。
WITH RECURSIVE UNITS_PARENT (ID ,NAME, PARENT_ID) AS (# 递归体的开始,所有的父级下子单位,根据这个语句产生递归体的初始行,并将这些初始行数据插入到UNITS_PARENT临时表中。SELECT U.ID, U.NAME, U.PARENT_ID FROM UNITS AS U WHERE U.PARENT_ID IS NULL UNION ALL # 递归的开始,将根据UNITS_PARENT表中的初始行数据和UNITS表进行真正的递归查询,直到不在产生新的数据行为止,也就是递归结束,并将查询的数据插入到UNITS_PARENT临时表中。# 注意ON的条件:UNITS_PARENT中初始行数据存的是所有的上级单位信息,向下查询,那就是查询所有的PARENT_ID等于初始行ID的数据。SELECT U.ID, U.NAME, U.PARENT_ID FROM UNITS_PARENT AS UP JOIN UNITS AS U ON UP.ID = U.PARENT_ID
)
# 从UNITS_PARENT临时表查询出所有的符合要求的数据
SELECT ID ,NAME, PARENT_ID FROM UNITS_PARENT ORDER BY ID;#|ID |NAME |PARENT_ID|
-+------+--------+---------+
1| 1500|1500单位 | |
2| 1501|1501单位 | 1500|
3| 1600|1600单位 | |
4| 1601|1601单位 | 1600|
5| 1602|1602单位 | 1600|
6| 15011|15011单位 | 1501|
7| 15012|15012单位 | 1501|
8|150121|150121单位| 15012|
根据指定单位向下查询属于该单位的所有的子单位:
# WITH RECURSIVE是MySQL8支持的递归关键字。
WITH RECURSIVE UNITS_PARENT (ID ,NAME, PARENT_ID) AS (# 递归体的开始,1600下子单位,根据这个语句产生递归体的初始行,并将这些初始行数据插入到UNITS_PARENT临时表中。SELECT U.ID, U.NAME, U.PARENT_ID FROM UNITS AS U WHERE U.PARENT_ID = 1600 UNION ALL # 递归的开始,将根据UNITS_PARENT表中的初始行数据和UNITS表进行真正的递归查询,直到不在产生新的数据行为止,也就是递归结束,并将查询的数据插入到UNITS_PARENT临时表中。# 注意ON的条件:UNITS_PARENT中初始行数据存的是1600单位信息,向下查询,那就是查询所有的PARENT_ID等于初始行1600 ID的数据。SELECT U.ID, U.NAME, U.PARENT_ID FROM UNITS_PARENT AS UP JOIN UNITS AS U ON UP.ID = U.PARENT_ID
)
# 从UNITS_PARENT临时表查询出所有的符合要求的数据
SELECT ID ,NAME, PARENT_ID FROM UNITS_PARENT ORDER BY ID;#|ID |NAME |PARENT_ID|
-+----+------+---------+
1|1601|1601单位| 1600|
2|1602|1602单位| 1600|
根据子单位向上查询属于该单位的所有的上级单位,如果不要包含指定的子单位,那就在结果集中过滤掉即可:
# WITH RECURSIVE是MySQL8支持的递归关键字。
WITH RECURSIVE UNITS_PARENT (ID ,NAME, PARENT_ID) AS (# 递归体的开始,查询1501的所有上级单位,根据这个语句产生递归体的初始行,并将这些初始行数据插入到UNITS_PARENT临时表中。SELECT U.ID, U.NAME, U.PARENT_ID FROM UNITS AS U WHERE U.ID = 1501UNION ALL # 递归的开始,将根据UNITS_PARENT表中的初始行数据和UNITS表进行真正的递归查询,直到不在产生新的数据行为止,也就是递归结束,并将查询的数据插入到UNITS_PARENT临时表中。# 注意ON的条件:UNITS_PARENT中初始行数据存的是1501单位信息,向上查询,那就是查询所有ID等于初始行PARENT_ID的数据。SELECT U.ID, U.NAME, U.PARENT_ID FROM UNITS_PARENT AS UP JOIN UNITS AS U ON U.ID = UP.PARENT_ID
)
# 从UNITS_PARENT临时表查询出所有的符合要求的数据
SELECT ID ,NAME, PARENT_ID FROM UNITS_PARENT ORDER BY ID;#|ID |NAME |PARENT_ID|
-+----+------+---------+
1|1500|1500单位| |
2|1501|1501单位| 1500|
相关文章:

Mysql8和Oracle实际项目中递归查询树形结构
背景: 项目升级,引入MySQL数据库,之前一直用的是Oracle数据,在做用户登录单位维护的时候,需要返回该用户所属单位下的所有子单位。下边是模拟项目数据实践的过程。 数据准备: 准备一张单位表,…...

docker mysql8 设置不区分大小写
docker安装Mysql8.0的坑之lower_case_table_names_docker mysql lower_case_table_names-CSDN博客https://blog.csdn.net/p793049488/article/details/108365929 docker run ‐di ‐‐nametensquare_mysql ‐p 33306:3306 ‐e MYSQL_ROOT_PASSWORD123456 mysql...

Audio Siganl (MATLAB) 代码学习—常见问题3
问题描述 生成信号y1: 8000个样本,1000个周期,幅度为0.85的余弦信号。若信号的持续时间为1s,则采样频率和信号频率为多少。生成信号y2: 持续时间为1s,幅度为0.7,频率为500Hz,相位为 π / 4 \pi/4 π/4生成信号y:y_1+y_2绘制前200ms的y信号示意图计算y的DFT绘制频域示意图…...

【PTA题目】7-8 矩阵运算 分数 10
7-8 矩阵运算 分数 10 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 给定一个nn的方阵,本题要求计算该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。副对角线为从矩阵的右上角至左下角的连线。 输入格式: 输入第一行给出正整数n(…...

Ubuntu20.04创建并挂在zfs池
Ubuntu 下使用 ZFS [适用于中高级用户] 主磁盘上清洁安装带有ZFS的Ubuntu后,可以开始体验其特性。 所有ZFS配置过程都需要命令行。 我不知道有GUI工具。 创建一个 ZFS 池 本节仅适用于具有多个磁盘的系统。 如果只有一个磁盘,Ubuntu会在安装时自动创建…...

x的平方根算法(leetcode第69题)
题目描述: 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。…...

打破空间限制,畅享真实生活
直播已经成为了当今社会中非常流行的一种娱乐方式,也是人们获取信息和互动的重要渠道之一。而无绿幕直播,则是近年来兴起的一种特殊形式,它打破了以往直播的空间限制,让观众们能够更贴近主播,更真实地感受到直播背后的…...

Python基础期末复习 新手 2
虽然age 10在__init__方法中定义了一个局部变量age,但这个局部变量并不会影响类属性age的值。类属性是在类级别上定义的,不属于任何一个实例。因此,在创建实例s1和s2时,它们的age属性值都为类属性的初始值0。 尽管对类的属性值进…...

Java接入ChatGPT接口简单示例
我们定义了一个名为ChartGPTConfig的类,它有两个私有成员变量apiKey和apiUrl,分别表示ChartGPT的API密钥和API URL。 public class ChartGPTConfig {private final String apiKey;private final String apiUrl;public ChartGPTConfig(String apiKey, St…...

解决夜神模拟器与Android studio自动断开的问题
原因:夜神模拟器的adb版本和Android sdk的adb版本不一致 解决办法: 1.找到android的sdk (1)File--->Project Structure (2)SDK Location:记下sdk的位置 2.找到sdk中的adb文件 SDK-->platform-tools-->adb.exe 3.复制…...

利用C语言模拟实现堆的基本操作和调堆算法
利用C语言模拟实现堆的基本操作和调堆算法 文章目录 利用C语言模拟实现堆的基本操作和调堆算法前言一、堆的基本原理大根堆和小根堆的比较 二、实现堆的基本操作1)结构定义2)初始化堆(HeapInit)3)销毁堆(He…...

react hooks之useRef和useImperativeHandle
为什么这两个一起写,是因为这两个关联性很大,逐一介绍。 一:useRef 1、作用:用于在函数组件中创建一个持久化的引用变量。这个引用变量可以在组件的多次渲染之间保持不变,并且可以访问和修改 DOM 元素或其他组件实例…...

scala方法与函数
定义方法定义函数方法和函数的区别scala的方法函数操作 1.9 方法与函数 1.9.1 定义方法 定义方法的基本格式是: def 方法名称(参数列表):返回值类型 方法体 def add(x: Int, y: Int): Int x y println(add(1, 2)) // 3 //也…...

前端框架(Front-end Framework)和库(Library)的区别
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

mysql原理--B+树索引的使用
1.索引的代价 在介绍如何更好的使用索引之前先要了解一下使用这玩意儿的代价,它在空间和时间上都会拖后腿: (1). 空间上的代价 这个是显而易见的,每建立一个索引都要为它建立一棵 B 树,每一棵 B 树的每一个节点都是一个数据页&…...

Android : Room 数据库的基本用法 —简单应用_三_版本
在实体类中添加了新字段: Entity(tableName "people") public class People {//新添加的字段private String email;public String getEmail() {return email;}public void setEmail(String email) {this.email email;}} 再次编译启动时会报错…...

微服务网关组件Gateway实战
1. 需求背景 在微服务架构中,通常一个系统会被拆分为多个微服务,面对这么多微服务客户端应该如何去调用呢?如果根据每个微服务的地址发起调用,存在如下问题: 客户端多次请求不同的微服务,会增加客户端代码…...

目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】三维重建(补充篇)
目录 前言 算法原理 三维重建意义 三维重建定义 常见的三维重建表达方式...

关于uniapp X 的最新消息
uni-app x 是什么? uni-app x,是下一代 uni-app,是一个跨平台应用开发引擎。 uni-app x 没有使用js和webview,它基于 uts 语言。在App端,uts在iOS编译为swift、在Android编译为kotlin,完全达到了原生应用的…...

spark从表中采样(随机选取)一定数量的行
在Spark SQL中,你可以使用TABLESAMPLE来按行数对表进行采样。以下是使用TABLESAMPLE的示例: SELECT * FROM table_name TABLESAMPLE (1000 ROWS);在这个示例中,table_name是你要查询的表名。TABLESAMPLE子句后面的(1000 ROWS)表示采样的行数…...

java定位系统源码,UWB技术的无线定位系统源码
UWB技术是一种传输速率高,发射功率较低,穿透能力较强并且是基于极窄脉冲的无线技术。UWB最优的应用环境是室内或者相对密闭的空间,有着厘米级的定位精度,不仅可以非常精准地进行位置跟踪,还可以快速地进行数据传输。 智…...

阿里云sls日志服务如何查某个具体字段的平均数
1: 需求: 查询线上某个接口(如:list_new)的成功率和时延 查接口时延的写法在网上找了一堆,都是语法错误,最后在阿里云官方api找到了正确的 2:贴一下阿里云官方文档: 聚…...

Java八股文面试全套真题【含答案】- Maven篇
以下是一些关于Maven的经典面试题以及它们的答案: 什么是Maven? Maven是一个项目管理工具,用于构建、发布和管理Java项目。它提供了一种标准化的项目结构、依赖管理和构建过程。Maven的核心概念是什么? Maven的核心概念包括POM文…...

从零构建属于自己的GPT系列6:模型本地化部署2(文本生成函数解读、模型本地化部署、文本生成文本网页展示、代码逐行解读)
🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1:数据预处理 从零构建属于自己的GPT系列2:模型训…...

不同品牌的手机如何投屏到苹果MacBook?例如小米、华为怎样投屏比较好?
习惯使用apple全家桶的人当然知道苹果手机或iPad可以直接用airplay投屏到MacBook。 但工作和生活的多个场合里,并不是所有人都喜欢用同一品牌的设备,如果同事或同学其他品牌的手机需要投屏到MacBook,有什么方法可以快捷实现? 首先…...

路由和网络周期
### 路由(Routing): 1. **路由的概念:** 路由是用于确定用户在网站或应用程序中所处位置的机制。它可以将不同的 URL 映射到对应的页面或视图组件,使得用户可以通过不同的 URL 访问不同的内容。 2. **路由器…...

【算法与数据结构】332、LeetCode重新安排行程
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题比较属于困难题目,难点在于完成机票、出发机场和到达机场之间的映射关系,再…...

阶段五:深度学习和人工智能(掌握使用TensorFlow或PyTorch进行深度学习)
掌握使用TensorFlow或PyTorch进行深度学习需要具备一定的编程基础和数学基础,包括编程语言、数据结构、算法、线性代数、概率论和统计学等方面的知识。以下是掌握使用TensorFlow或PyTorch进行深度学习的一些基本要求: 了解深度学习的基本概念和原理&…...

DevEco Studio IDE 创建项目时候配置环境
DevEco Studio IDE 创建项目时候配置环境 一、安装环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、在配置向导的时候意外关闭配置界面该如何二次配置IDE环境。 打开IDE的界面是这样的。 点击Create Project进行环境配置。 点击OK后出现如…...

HTML面试题---专题二
文章目录 一、前言二、解释input标签中占位符属性的用途三、如何在 HTML 中设置复选框或单选按钮的默认选中状态?四、表单输入字段中必填属性的用途是什么?五、如何使用 HTML 创建表格?六、解释a标签中目标属性的用途七、如何创建一个点击后会…...