SQL中获取树形结构所有子级数据

本文介绍了一种使用SQL存储过程来获取树形结构中所有子节点的方法,包括节点自身。通过递归公用表表达式(CTE)实现高效查询。

今天做一个权限菜单。要获取树形结构下面的所有节点。

想到的思路有2种。

1.c#获取所有树的数据,然后递归处理

2.SQL里面就处理完

 

最终还是考虑用SQL写存储过程处理。(数据量大Proc性能好)

具体代码如下:

/*
获取树形结构的所有子节点,包括自己本身
*/
ALTER proc [dbo].[SP_GetChirldsByParentId]
@IdValue nvarchar(20),
@TableName nvarchar(20),
@IdFiledName nvarchar(20),
@ParentFieldName nvarchar(20)
as
declare @sql nvarchar(800)
set @sql = 'with cte as
(
select '+@TableName+'.* from '+@TableName+' where '+@IdFiledName+' = @Id
union all
select a.* from '+@TableName+' a join cte b on a.'+@ParentFieldName+' = b.'+@IdFiledName+'
)
select * from cte'
print @sql
go
EXEC SP_EXECUTESQL @Sql, N'@Id NVARCHAR',@Id=@IdValue

  

转载于:https://www.cnblogs.com/hujunmin/p/4844319.html

在 MySQL 中查询树形结构数据时,若需获取某个父节点下的所有子节点(包括直接子节点和间接子节点),通常可以采用递归查询的方式。MySQL 8.0 引入了 **Common Table Expressions(CTE)**,支持递归查询,从而可以高效地实现此类需求。 以下是一个使用递归 CTE 查询指定父节点下所有子节点的示例: ### 示例数据结构 假设存在一个名为 `categories` 的表,用于存储树形结构的分类数据: ```sql CREATE TABLE categories ( id INT PRIMARY KEY, name VARCHAR(100), parent_id INT ); ``` ### 递归查询语句 若要查询 `id = 1` 的节点下所有子节点(包括其自身),可以使用如下 SQL: ```sql WITH RECURSIVE category_tree AS ( SELECT id, name, parent_id FROM categories WHERE id = 1 -- 指定的父节点 UNION ALL SELECT c.id, c.name, c.parent_id FROM categories c INNER JOIN category_tree t ON c.parent_id = t.id ) SELECT * FROM category_tree; ``` 此查询将返回从指定节点开始的所有节点,包括层嵌套的所有子节点。 ### 传统方式(MySQL 5.x) 在不支持递归查询的 MySQL 版本中,可以通过变量模拟递归查询。例如: ```sql SELECT GROUP_CONCAT(id) INTO @ids FROM categories WHERE id = 1; WHILE @ids IS NOT NULL DO SELECT GROUP_CONCAT(id) INTO @ids FROM categories WHERE FIND_IN_SET(parent_id, @ids); IF @ids IS NOT NULL THEN INSERT INTO temp_table SELECT * FROM categories WHERE FIND_IN_SET(id, @ids); END IF; END WHILE; SELECT * FROM temp_table; ``` 这种方式依赖于临时表和变量操作,适用于 MySQL 5.x 环境,但实现较为复杂,且性能可能不如递归 CTE。 ### 函数实现 还可以创建一个函数来返回指定节点下的所有子节点 ID 列表: ```sql DELIMITER // CREATE FUNCTION get_all_children_ids(targetId INT) RETURNS TEXT DETERMINISTIC BEGIN DECLARE ids TEXT; SET ids = CAST(targetId AS CHAR); WHILE ids IS NOT NULL DO SET @next_ids = NULL; SELECT GROUP_CONCAT(id) INTO @next_ids FROM categories WHERE FIND_IN_SET(parent_id, ids); IF @next_ids IS NOT NULL THEN SET ids = @next_ids; SET @ids_list = CONCAT(@ids_list, ',', ids); ELSE SET ids = NULL; END IF; END WHILE; RETURN @ids_list; END // DELIMITER ; ``` 调用该函数即可获取所有子节点: ```sql SELECT * FROM categories WHERE FIND_IN_SET(id, get_all_children_ids(1)); ``` ### 注意事项 - 使用递归 CTE 时,需确保 MySQL 版本为 8.0 或以上。 - 若数据较深,应适当调整 `cte_max_recursion_depth` 系统变量。 - 对于频繁查询结构的场景,可考虑使用嵌套集模型(Nested Set Model)以提高性能[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值