相关文章推荐
温文尔雅的灌汤包  ·  Issue when check ...·  1 年前    · 
安静的苦瓜  ·  python 提取日期的月份 ...·  2 年前    · 
从容的柚子  ·  Android - Android R ...·  2 年前    · 

需求: 查出当前用户下面所有的子用户信息. ( 传递父类id )
分析:
方法一:   使用Java程序进行遍历查询. ( 一条一条查询, 执行效率低 )
方法二:   sql递归查询. ( 单句查询, 效率比遍历查询高! )

1.库表结构如下: ( 自关联的 - 无限级用户表 ) 在这里插入图片描述

2.sql语句实现需求:

2.1 查所有的叶子节点 . ( 不含自己 )
SELECT u2.id, u2.name
FROM( 
     SELECT 
		@ids AS p_ids, 
		(SELECT @ids := GROUP_CONCAT(id) FROM test_user WHERE FIND_IN_SET(parentId, @ids)) AS c_ids, 
		@l := @l+1 AS LEVEL 
     FROM test_user, (SELECT @ids := '101', @l := 0 ) b  #此处为需要传递的父类id. 
     WHERE @ids IS NOT NULL 
JOIN test_user u2
ON FIND_IN_SET(u2.id, u1.p_ids)  AND u2.id != '101'  #需要包含自己, 则删掉 !=
2.2 查所有的父节点. ( 含自己 )
SELECT u2.id, u2.name 
FROM( 
     SELECT
            @id c_ids,
            (SELECT @id:=GROUP_CONCAT(parentId) FROM test_user WHERE FIND_IN_SET(id,@id)) p_ids,
            @l := @l+1 AS LEVEL 
     FROM test_user,(SELECT @id:='105', @l := 0) b
     WHERE @id IS NOT NULL
JOIN test_user u2  ON u1.c_ids = u2.id  

3.执行过程剖析. ( 中间部分 )

3.1 ( select @ids := ‘101’, @l := 0 )

作用:   初始化一个临时表. ( 存放当前父类id )
在这里插入图片描述

  • @变量名 : 定义一个用户变量.
  • : = 对该用户变量进行赋值.
    用户变量赋值有两种方式:     一种是直接用"=“号,另一种是用”:=“号。
    其区别在于:
          使用set命令对用户变量进行赋值时,两种方式都可以使用;
          用select语句时,只能用”:=“方式,因为select语句中,”="号被看作是比较操作符。
3.2 WHERE @ids IS NOT NULL

      查询条件, 也是终止条件. ( 若为空(没有子节点了), 即终止! )
 

3.3 GROUP_CONCAT() 函数

含义:
         用于将多个字符串拼接成1个字符串! ( 即行转列. )

完整的语法如下:

   group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符']) 
3.4 FIND_IN_SET(str, strList)

含义:
         查询字段(strList)中包含的结果,返回结果null或记录。

  • str : 要查询的字符串.
  • strList : 字段名,参数以“,”分隔,如(1,2,6,8)
需求:  查出当前用户下面所有的子用户信息. ( 传递父类id )分析:        方法一:   使用Java程序进行遍历查询. ( 一条一条查询, 执行效率低 )        方法二: &nb...
mysql实现递归查询的方法:首先创建,并初始化数据;然后向下递归,利用【find_in_set()】函数和【group_concat()】函数实现递归查询。 本教程操作环境:windows7系统、mysql8.0.22版,该方法适用于所有品牌电脑。 免费学习推荐:mysql教程(视频) mysql实现递归查询的方法: 1、创建 DROP TABLE IF EXISTS `t_areainfo`; CREATE TABLE `t_areainfo` ( `id` i.
还是上次那一个,要加上条件,推荐人被推荐人都得符合条件。 这个sql写了3小时。要求一条sql查询所有符合条件的id及其对应的推荐id,推荐id也有脏数据得去过滤。感到一个查了查去,绕晕了。 大家对此sql没有啥好优化的建议。我提议废了这个接口。 改成多次遍历去查,用代码实现就简单多了。于是废了。 CREATE TABLE `wq_areainfo` ( `id` int(11) NOT null AUTO_INCREMENT, `level` int(11) DEFAULT 0 , `name` varchar(255) DEFAULT '0', `pa... id int(11) NOT null AUTO_INCREMENT, level int(11) DEFAULT 0 , name varchar(255) DEFAULT ‘0’, parentId int(11) DEFAULT 0, status int(11) DEFAULT 0, PRIMARY KEY (id) 最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。 但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 应该怎么实现呢? 于是,就有了这篇文章。 文章主要知识点: Oracle 递归查询, start with connect by prior 用法 find_in_set 函数 concat,concat_ws,group_concat 函数 MySQL 自定义函数 手动实现 MySQL
MySQL支持递归查询所有子的功能,可以通过使用WITH RECURSIVE关键字来完成。具体的做法如下: 使用WITH RECURSIVE关键字定义递归查询语句的开始部分,并指定初始条件,如起始节点的ID; 在递归查询语句的SELECT子句,列需要查询的字段,并将递归所需的连接在一起; 在FROM子句使用子查询来连接两个相同,同时在其使用递归查询语句来找到所有的子节点; 在WHERE子句设置递归结束的条件,如判断是否到达了叶子节点,从而结束递归循环; 最后,在主查询语句递归查询语句作为子查询并指定需要输的字段。 例如,假设有一个格名为“tree”,用于记录数据的层次结构,其有两个字段——"id"和"parent_id",分别示该节点的ID和它的父节点的ID。为递归查询获取所有子,可以如下实现: WITH RECURSIVE cte AS ( SELECT id, parent_id FROM tree WHERE id = 1 --设置开始节点的ID UNION ALL SELECT t.id, t.parent_id FROM tree t JOIN cte ON cte.id = t.parent_id --连接格,并使用递归查询语句来查找所有的子节点 WHERE t.id != cte.id --设置递归结束的条件,这里是避免重复查询 SELECT id, parent_id --输需要查询的字段 FROM cte; 通过以上语句,即可查询到"tree"所有以ID为1的节点为根节点的子节点。如果想要查询"tree"所有节点的子节点,只需将初始条件改为NULL。 总之,MySQL支持递归查询所有子的功能,通过使用WITH RECURSIVE关键字,将递归查询语句嵌套在SELECT语句即可实现。