MYSQL中如何根据父类递归查询出所有的子类 ? ( 自关联 - 无限级关系表 )

作者: 分类: php 发布时间: 2022-09-23 21:45 浏览人数:8
 

需求:查出当前分类下面所有的子分类信息。(传递父类id)

分析:
方法一:使用PHP程序进行遍历查询。(一条一条查询,执行效率低)
方法二:sql递归查询。(单句查询,效率比遍历查询高!)

1.库表结构如下:(自关联的 - 无限级分类表)



2.SQL语句实现需求:

2.1 查询所有的叶子节点(不包含自己):

SELECT
	u2.id,
	u2.NAME 
FROM
	(
	SELECT
		@ids AS p_ids,
		( SELECT @ids := GROUP_CONCAT( id ) FROM table_name WHERE FIND_IN_SET( parent_id, @ids ) ) AS c_ids,
		@l := @l + 1 AS LEVEL 
	FROM
		table_name,
		( SELECT @ids := "8", @l := 0 ) b #此处为需要传递的父类id
	WHERE
		@ids IS NOT NULL 
	) u1
	JOIN stpc_wood_class u2 ON FIND_IN_SET( u2.id, u1.p_ids ) 
	AND u2.id != "8" #需要包含自己, 则删掉 !=

2.2 查询所有的父节点(包含自己)

SELECT
	u2.id,
	u2.NAME 
FROM
	(
	SELECT
		@id c_ids,
		(
		SELECT
			@id := GROUP_CONCAT( parent_id ) 
		FROM
			table_name 
		WHERE
		FIND_IN_SET( id, @id )) p_ids,
		@l := @l + 1 AS LEVEL 
	FROM
		table_name,(
		SELECT
			@id := '42', #此处为要传递的子类id
			@l := 0 
		) b 
	WHERE
		@id IS NOT NULL 
	) u1
	JOIN table_name u2 ON u1.c_ids = u2.id

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


3.1 (SELECT @ids := "34", @l := 0)


  • @变量名 : 定义一个用户变量
  • :=
  • 对该用户变量进行赋值。用户变量赋值有两种方式:一种是直接用“=”号,另一种是用“:=”号。 其区别在于:
    • 使用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)
使用:


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!