数据表结构

id    name  parent_id

1        A        0

2        B        1

3        C        1

4        D        2

5        E        4

6        F        1

7        G        1

注:parent_id 为0表示顶级父节点,即A是顶级父辈,没有父节点

转储SQL表结构及数据

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------

-- Table structure for demo

-- ----------------------------

DROP TABLE IF EXISTS `demo`;

CREATE TABLE `demo` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(255) NOT NULL,

`parent_id` int(11) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of demo

-- ----------------------------

INSERT INTO `demo` VALUES ('1', 'A', '0');

INSERT INTO `demo` VALUES ('2', 'B', '1');

INSERT INTO `demo` VALUES ('3', 'C', '1');

INSERT INTO `demo` VALUES ('4', 'D', '2');

INSERT INTO `demo` VALUES ('5', 'E', '4');

INSERT INTO `demo` VALUES ('6', 'F', '1');

INSERT INTO `demo` VALUES ('7', 'G', '1');

需求:根据一个子ID,查询所有父类

SQL如下:

SELECT T2.id, T2.name

FROM (

SELECT

@r AS _id,

(SELECT @r := parent_id FROM demo WHERE id = _id) AS parent_id,

@l := @l + 1 AS lvl

FROM

(SELECT @r := 5, @l := 0) vars,

demo h

WHERE @r <> 0) T1

JOIN demo T2

ON T1._id = T2.id

ORDER BY T1.lvl DESC结果如下

id      name

1         A

2         B

4         D

5         E

分析过程(答疑过程)

我使用将SQL语句拆分的方式,并展示每句SQL运行结果,让各位可以看的更明白,以便于根据你自己的业务需求进行更改

1、先不管T2,先把T1的SQL抽出来看

SELECT

@r AS _id,

(SELECT @r := parent_id FROM demo WHERE id = _id) AS parent_id,

@l := @l + 1 AS lvl

FROM

(SELECT @r := 5, @l := 0) vars,

demo h

WHERE @r <> 0

运行结果

从这里可以看出,其实T1已经找出ID为5节点的所有父节点了,和T2(即demo表)进行左连接,只不过是为了根据Id获取Name而已。而且还可以看出@l其实在整个SQL中并没有什么作用,只是用来标识节点的等级,底级子节点的lvl为1,父节点lvl值越大表示越靠近顶级父节点,想象一下树结构,你就明白了

2、搞明白@r := 5

SELECT @r := 5, @l := 0

运行结果

这里看出,其实@r,@l 就是一个变量而已,

作为变量自然你可以随便起名,当然也可以随便赋值,改成@a,@b也都是可以的

那这句SQL的意思就出来了,它表示给变量@r赋值,值为5,给@l赋值,值为0

因此,其实整个SQL的意思也明了了就是根据子ID5,查询所有父类

3、搞懂变量@r 值如何变化

@r AS _id,

(SELECT @r := parent_id FROM demo WHERE id = _id) AS parent_id

根据MYSQL执行顺序(在文章末尾处),SQL语句在执行时会先执行From,即会先执行上一步的赋值操作,因此这里的_id值为5,所以上面的SQL等同于如下SQL

SELECT @r := parent_id FROM demo WHERE id = 5

运行结果

这句SQL肯定没人不会,但是有一个点很重要,它是整个执行过程的核心,就是@r := parent_id,它在查询Id为5的节点的父Id时,把这个父Id同时赋给了变量@r。因此@r值改变了,它从5变为了4。

这个时候思路就很清晰了,只要我们设置限制条件,让SQL在@r为0的时候结束循环就OK了

4、<>符号的含义

WHERE @r <> 0

这个就没什么好说的了,<>符号在MYSQL中表示不等于,这就是我们在第四步中所说的限制条件,它限制了@r这个变量不能等于0。所以当@r不等于0时,SQL语句会根据子ID向上查询父ID,又把父ID当做子ID赋值给@r,再次向上查询,直至@r变量的值为0为止。

补充:如果业务不需要,可以完全可以去掉@l变量

SELECT ,

@a AS _id,

(SELECT @a := parent_id FROM demo WHERE id = _id) AS parent_id

FROM

(SELECT @a := 5) vars,

demo h

WHERE @a <> 0

运行结果

可以看出@l其实在整个SQL中并没有什么作用,只是用来标识节点的等级,这也证实了我们上述第一步的关于@l的解释

因为这个过程很类似于JAVA通过构造树结构向上递归查询的方式,所以这个SQL形式被很多人叫做MYSQL递归查询

文章结尾

关于MYSQL的查询顺序

FROM

ON

JOIN

WHERE

GROUP By

CUBE|ROllUP

HAVING

SELECT

DISTINCT

ORDER BY

LIMIT

最先执行的是FROM操作,最后执行的是LIMIT操作。每个操作都会产生一个虚拟表,该虚拟表作为一个处理的输入

mysql 递归查找父节点_MYSQL递归查询,根据子类ID查询所有父类(最全)相关推荐

  1. mysql 递归查找父节点_MySQL递归查询树状表的子节点、父节点具体实现

    简介:mysql5.0.94版本,该版本以及较高级的版本(5.5.6等等)尚未支持循环递归查询,和sqlserver.oracle相比,mysql难于在树状表中层层遍历的子节点.本程序重点参考了下面的 ...

  2. mysql 递归查找父节点_MYSQL递归查询所有父节点

    1.表结构:CREATE TABLE `t_busi_system` ( `ID` varchar(64) NOT NULL COMMENT '标识', `PARENT_ID` varchar(64) ...

  3. mysql递归查找父节点

    参照https://blog.csdn.net/weixin_35756522/article/details/8187653 s2表结构如下: set @a=6; select @a as _id, ...

  4. mysql 自定义函数 递归查找父节点

    1.问题描述: 现有一树形机构数据表,只有子父关系,需找到每行数据 从本节点到跟节点的路径 如: 99AA 的 path 应该为 /99AA / A000的 path 应该为 /99AA/A000/ ...

  5. MYSQL递归查询,根据子类ID查询所有父类(宇宙第一详细教程)

    前言 工作中业务需求碰到了MYSQL递归这个点,网上资料大都抄来抄去,虽然代码的确能运行.但是萌新是真的看不懂这SQL写的什么玩意啊,看底下评论很多人提问皆是未回复,自己狠下心花了一上午时间,把这个点 ...

  6. 如何通过递归找父节点或子节点详解

    前言:如何通过递归去查询父节点或子节点,相信大家在平常肯定会遇到这样的需求,这一章我们就好好研究下如何用递归去找. 目录 一.递归找父节点或子节点 二.创建一张表关系表保存上面的关系 三.递归查询父节 ...

  7. 递归删除父节点及所有子节点(转)

    --递归删除父节点及所有子节点create table tb(Id int, ParentId int, Name varchar(5))insert into tb select 1, 0, 'a1 ...

  8. Java根据子节点查找父节点

    /*** 根据节点查找父节点* @param label* @return*/public static Label getParentLabelObject(Label label,List< ...

  9. mysql 获取根节点_mysql递归查询根节点

    同时查询2张表, 查询学生所在的班级 mysql> select xing_ming,ban_ming from xue_sheng,ban_ji; 别名的使用 mysql> select ...

最新文章

  1. 010-012列表:一个打了激素的数组
  2. 阿里内核月报2015年03月
  3. 程序员面试题精选100题(13)-第一个只出现一次的字符[算法]
  4. python基础课程_2学习笔记3:图形用户界面
  5. HGAT-用于半监督短文本分类的异构图注意力网络
  6. linux中文件输出输入,linux中文件输入输出的管理
  7. android支持平台,Android 平台功能
  8. USACO_1_2_Dual Palindromes
  9. Subway Pursuit (二分)(交互题)
  10. 分类算法学习(三)——逻辑回归算法的原理及简单实现
  11. 【通信】基于matlab GUI循环码编译码器【含Matlab源码 692期】
  12. 基于springboot在线租车管理系统
  13. php电竞酒店系统,电竞酒店系统管理@电竞酒店云管家@电竞酒店解决方案
  14. 穿越东西冲、感受户外、爱上运动
  15. Python——组合数据类型(字符串、元组、列表、字典)转换总结
  16. web3应用与dApp理解
  17. vue+环信客服前端对接
  18. Morsel-Driven Parallelism: 一种NUMA感知的并行Query Execution框架
  19. Jquery-canvas动态粒子背景动画-适用于登陆注册页面背景
  20. terracotta安装配置与集群过程

热门文章

  1. 关于 SAP Spartacus 电商云 UI feature level 的测试步骤
  2. 如何使用代码创建和读取 SAP CRM 订单的 Text 数据
  3. Linux Boot,Kernel 和 Service 介绍
  4. 如何在SAP Spartacus的scss里引入全局变量
  5. 一段简单的JavaScript代码,实现在同一网页输出多个图标的功能
  6. SAP Fiori Elements - fixed value help data request and how drop down list entry is rendered
  7. SAP ABAP和C4C,Hybris Commerce里一些性能分析工具
  8. SAP ABAP Netweaver和Hybris Commerce的部署策略
  9. Fiori Elements detail table data request logic
  10. SAP CRM Opportunity response area