【MySQL基础】MySql如何根据输入的id获得树形结构的子节点列表:使用自连+SUBSTRING_INDEX函数

有如下树形结构:RT-ST-SST-SSST共四层,RT是根节点,往后依次是一代子节点,二代子节点,三代子节点。
如何根据当前节点的id,获得其子节点呢?这是一个SQL问题。加入传入的id为1(即根节点),使用自连+SUBSTRING_INDEX函数得到其子节点:
(本文章分享在CSDN平台,更多精彩请阅读 东陆之滇的csdn博客:http://blog.csdn.net/zixiao217)

示例:

id     name    type   url
1      大树    RT      root

树形结构视图:

--大树
	+--树干1
		+--树枝1
			+--树叶1
			+--树叶2
		+--树枝2
	+--树干2
		+--树枝3
			+--树叶3

建表SQL:

create table tree_node(id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(200), type VARCHAR(30),url VARCHAR(200));

插入基础数据SQL:

insert into tree_node(name, type, url) values('大树', 'RT', 'root');

insert into tree_node(name, type, url) values('树干1', 'ST', 'root/tree_main_line1');
insert into tree_node(name, type, url) values('树干2', 'ST', 'root/tree_main_line2');

insert into tree_node(name, type, url) values('树枝1', 'SST', 'root/tree_main_line1/tree_branche1');
insert into tree_node(name, type, url) values('树枝2', 'SST', 'root/tree_main_line1/tree_branche2');
insert into tree_node(name, type, url) values('树枝3', 'SST', 'root/tree_main_line2/tree_branche3');

insert into tree_node(name, type, url) values('树叶1', 'SSST', 'root/tree_main_line1/tree_branche1/tree_leaf1');
insert into tree_node(name, type, url) values('树叶2', 'SSST', 'root/tree_main_line1/tree_branche1/tree_leaf2');
insert into tree_node(name, type, url) values('树叶3', 'SSST', 'root/tree_main_line2/tree_branche3/tree_leaf3');

查看刚刚插入的数据:

mysql> select * from tree_node;
+----+---------+------+-----------------------------------------------+
| id | name    | type | url                                           |
+----+---------+------+-----------------------------------------------+
|  1 | 大树    | RT   | root                                          |
|  2 | 树干1   | ST   | root/tree_main_line1                          |
|  3 | 树干2   | ST   | root/tree_main_line2                          |
|  4 | 树枝1   | SST  | root/tree_main_line1/tree_branche1            |
|  5 | 树枝2   | SST  | root/tree_main_line1/tree_branche2            |
|  6 | 树枝3   | SST  | root/tree_main_line2/tree_branche3            |
|  7 | 树叶1   | SSST | root/tree_main_line1/tree_branche1/tree_leaf1 |
|  8 | 树叶2   | SSST | root/tree_main_line1/tree_branche1/tree_leaf2 |
|  9 | 树叶3   | SSST | root/tree_main_line2/tree_branche3/tree_leaf3 |
+----+---------+------+-----------------------------------------------+

加入传入的id为1(即根节点),使用自连+SUBSTRING_INDEX函数得到其子节点:

mysql> select tree1.* from tree_node as tree1
    -> join tree_node as tree2
    -> on SUBSTRING_INDEX(tree1.url,'/',1) = tree2.url
    -> and (length(tree1.url) - length(replace(tree1.url, '/', ''))) = 1
    -> where tree2.id = 1;
+----+---------+------+----------------------+
| id | name    | type | url                  |
+----+---------+------+----------------------+
|  2 | 树干1   | ST   | root/tree_main_line1 |
|  3 | 树干2   | ST   | root/tree_main_line2 |
+----+---------+------+----------------------+

解析SQL:

select tree1.* from tree_node as tree1
join tree_node as tree2
on SUBSTRING_INDEX(tree1.url,'/',1) = tree2.url
and (length(tree1.url) - length(replace(tree1.url, '/', ''))) = 1
where tree2.id = 1;


##返回"树干1"的父节点的url
select SUBSTRING_INDEX('root/tree_main_line1','/',1) 

##将"/"替换为""
mysql> select replace('root/tree_main_line1', '/', '');
+------------------------------------------+
| replace('root/tree_main_line1', '/', '') |
+------------------------------------------+
| roottree_main_line1                      |
+------------------------------------------+

##利用length差获得"/"的个数为1,则认为是子节点
mysql> select length('root/tree_main_line1') - length(replace('root/tree_main_line1', '/', ''));
+-----------------------------------------------------------------------------------+
| length('root/tree_main_line1') - length(replace('root/tree_main_line1', '/', '')) |
+-----------------------------------------------------------------------------------+
|                                                                                 1 |
+-----------------------------------------------------------------------------------+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值