SQL通过父节点获取所有子节点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL通过父节点获取所有子节点相关的知识,希望对你有一定的参考价值。

网上那些都看不懂啊 能不能给我详细解释解释

参考技术A 这个很简单啊
表结构一般如下tablename(表名)
id--节点ID, name-- 节点名称 parentid父节点ID,

-----获取节点号为6下的所有子节点
select * from tablename t start with id =6 connect by prior id=parentid
参考技术B create function GetSubNode_C(@parentid int)
returns @t table(Id int ,Name varchar(20),Parent_id int,Level int)
As
Begin
declare @Level int --等级根节点等级为1
set @Level=1
insert into @t select Id,Name,Parent_id,@Level from C where Id=@parentid
while @@rowcount>0 --如果至少有一条子节点
begin
set @Level=@Level+1
insert into @t select a.Id,a.Name,a.Parent_id,@Level from C a,@t b
where a.Parent_id in (select Id from C where Id=b.ID)
and b.Level=@Level-1
end
return
End
--该函数返回一个临时表
这个思路 查询当前ID是否含有子节点(where 父节点=当前ID) 有就继续 没有就循环终止本回答被提问者和网友采纳

MySQL 根据父ID获取所有子节点

MySQL根据父节点ID查出所有子节点

测试表

CREATE TABLE `dept` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` longtext,
  `pid` int(11) DEFAULT NULL,
  `status` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门表';

SQL

SELECT * 
FROM (
    SELECT
		t1.*,
        IF(FIND_IN_SET(`pid`, @pids) > 0, @pids := CONCAT(@pids, ',', `id`), 0) AS ancestors
    FROM
        ( SELECT * FROM `dept` AS t WHERE t.`status` = 1 ORDER BY t.`id` ASC ) AS t1,
        ( SELECT @pids := 14 ) AS t2
) AS t3
WHERE
	ancestors != 0
	or `id` = 14;

分析

  1. t1:获取所有状态正常的数据并升序排列
  2. t2:初始化@pids变量,它用于获取每条记录时缓存父ID
  3. FIND_IN_SET查询当前记录的父ID@pids中的位置。找不到就返回0
    3.1. 找到就将父id拼接到@pids末尾,以便下一条记录继续在@pids中找自己的父id
  4. 每一条记录都基于前一条执行时得到的@pids进行判断。
  5. 总结:使用此方案的前提是:
    5.1. 所有结点的【id】必需大于【父id】: id > pid。
    5.2. 所有 id 整体是一个升序状态。
    5.3. 如果5.1无法满足,有其他字段能保证查 t1 时,结点可以按【根>干>叶】进行升序排列也行。

用JS生成SQL

var 结果字段 = '*';
var 表名 = '`sys_dept`';
var 主键 = '`id`';
var 父主键 = '`pid`';
var 状态 = '`status`';
var 要查的主键 = 14;
var 包含当前结点 = true;

var sql = `SELECT $结果字段 
FROM (
    SELECT
		t1.*,
        IF(FIND_IN_SET($父主键, @pids) > 0, @pids := CONCAT(@pids, ',', $主键), 0) AS ancestors
    FROM
        ( SELECT * FROM $表名 AS t WHERE t.$状态 = 1 ORDER BY t.$主键 ASC ) AS t1,
        ( SELECT @pids := $要查的当前主键 ) AS t2
) AS t3
WHERE
	ancestors != 0
	$包含当前结点 ? `or $主键 = $要查的主键` : '';`;
console.log(sql);
copy(sql);

参考资料

笑虾:MySQL - 学习笔记 - SELECT语句

博客园 - 张亮java:https://www.cnblogs.com/zhangliang88/p/15910781.html

以上是关于SQL通过父节点获取所有子节点的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 根据父ID获取所有子节点

MySQL 根据父ID获取所有子节点

Mysql 通过父节点ID获取所有子节点数据函数

SQL语句查询出父节点下的所有子节点

sql根据子节点查出所有的父节点的

SQL语句查询出一个父节点下的所有子节点