数据库语句的递归查询求助
如图,在数据库中,除了最顶上的结点,每个结点都有一个user_id和parent_id,user_id指的是结点本身,panrent_id指的是本结点的父结点,我现在知道...
如图,在数据库中,除了最顶上的结点,每个结点都有一个 user_id 和 parent_id,user_id指的是结点本身,panrent_id指的是本结点的父结点,我现在知道了图中的user_id为32的一个结点,我想找出这个结点下面的所有的节点(包括它自己)的user_id,请问这个用mySQL的数据库语句怎么实现?谢谢了!
展开
5个回答
展开全部
应该是这样:
with qry as (select user_id,parent_id from tab where user_id = 32
union all
select tab.user_id,tab.parent_id from tab,qry
where tab.parent_id = qry.id)
select * from qry ;
我用mysql5.0.22,不支持上述语法,oracle就可以(sqlserver应该也可以):
create table tab1(user_id int, parent_id int);
insert into tab1 values(1,null);
insert into tab1 values(32,1);
insert into tab1 values(101,32);
insert into tab1 values(102,32);
insert into tab1 values(201,101);
insert into tab1 values(202,101);
insert into tab1 values(203,102);
insert into tab1 values(204,102);
select * from tab1;
with qry(user_id,parent_id) as (select user_id,parent_id from tab1 where user_id = 32
union all
select tab1.user_id,tab1.parent_id from tab1,qry
where tab1.parent_id = qry.user_id
)
select * from qry;
所以,mysql没有办法了,只有写函数,用循环来实现了。
with qry as (select user_id,parent_id from tab where user_id = 32
union all
select tab.user_id,tab.parent_id from tab,qry
where tab.parent_id = qry.id)
select * from qry ;
我用mysql5.0.22,不支持上述语法,oracle就可以(sqlserver应该也可以):
create table tab1(user_id int, parent_id int);
insert into tab1 values(1,null);
insert into tab1 values(32,1);
insert into tab1 values(101,32);
insert into tab1 values(102,32);
insert into tab1 values(201,101);
insert into tab1 values(202,101);
insert into tab1 values(203,102);
insert into tab1 values(204,102);
select * from tab1;
with qry(user_id,parent_id) as (select user_id,parent_id from tab1 where user_id = 32
union all
select tab1.user_id,tab1.parent_id from tab1,qry
where tab1.parent_id = qry.user_id
)
select * from qry;
所以,mysql没有办法了,只有写函数,用循环来实现了。
展开全部
就和C++写递归一样的吧~~
do while,如果这个点没有子节点了,就返回上一个节点
do while,如果这个点没有子节点了,就返回上一个节点
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
写一个函数,只查询某个节点的子节点,然后递归保存
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
-------- 写一个自定义函数 ---------
delimiter //
drop function if exists getChildren //
create function getChildren(pid int) returns varchar(500)
begin
declare childrenId varchar(500);
declare temp varchar(300);
set childrenID = "";
set temp = cast(pid as char);
while not isnull(temp) do
set childrenId = concat(childrenId, ",", temp);
select group_concat(user_id) into temp from 你的表名 where find_in_set(parent_id, temp) > 0;
end while;
return childrenId;
end //
delimiter ;
------------------
下面是调用的测试示例
------------------
mysql> select * from tree_recursion;
+----+--------+
| id | parent |
+----+--------+
| 1 | NULL |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 4 |
| 8 | 5 |
| 9 | 8 |
+----+--------+
9 rows in set (0.00 sec)
mysql> # 找节点 2 下的所有结点
mysql>
mysql> delimiter //
mysql> drop function if exists getChildren //
Query OK, 0 rows affected (0.00 sec)
mysql> create function getChildren(pid int) returns varchar(500)
-> begin
-> declare childrenId varchar(500);
-> declare temp varchar(300);
->
-> set childrenID = "";
-> set temp = cast(pid as char);
->
-> while not isnull(temp) do
-> set childrenId = concat(childrenId, ",", temp);
-> select group_concat(id) into temp from tree_recursion where find_in_set(parent, temp) > 0;
-> end while;
->
-> return childrenId;
-> end //
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> delimiter ;
mysql>
mysql> select * from tree_recursion where find_in_set(id, getChildren(2));
+----+--------+
| id | parent |
+----+--------+
| 2 | 1 |
| 4 | 2 |
| 5 | 2 |
| 7 | 4 |
| 8 | 5 |
| 9 | 8 |
+----+--------+
6 rows in set (0.02 sec)
mysql>
delimiter //
drop function if exists getChildren //
create function getChildren(pid int) returns varchar(500)
begin
declare childrenId varchar(500);
declare temp varchar(300);
set childrenID = "";
set temp = cast(pid as char);
while not isnull(temp) do
set childrenId = concat(childrenId, ",", temp);
select group_concat(user_id) into temp from 你的表名 where find_in_set(parent_id, temp) > 0;
end while;
return childrenId;
end //
delimiter ;
------------------
下面是调用的测试示例
------------------
mysql> select * from tree_recursion;
+----+--------+
| id | parent |
+----+--------+
| 1 | NULL |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 4 |
| 8 | 5 |
| 9 | 8 |
+----+--------+
9 rows in set (0.00 sec)
mysql> # 找节点 2 下的所有结点
mysql>
mysql> delimiter //
mysql> drop function if exists getChildren //
Query OK, 0 rows affected (0.00 sec)
mysql> create function getChildren(pid int) returns varchar(500)
-> begin
-> declare childrenId varchar(500);
-> declare temp varchar(300);
->
-> set childrenID = "";
-> set temp = cast(pid as char);
->
-> while not isnull(temp) do
-> set childrenId = concat(childrenId, ",", temp);
-> select group_concat(id) into temp from tree_recursion where find_in_set(parent, temp) > 0;
-> end while;
->
-> return childrenId;
-> end //
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> delimiter ;
mysql>
mysql> select * from tree_recursion where find_in_set(id, getChildren(2));
+----+--------+
| id | parent |
+----+--------+
| 2 | 1 |
| 4 | 2 |
| 5 | 2 |
| 7 | 4 |
| 8 | 5 |
| 9 | 8 |
+----+--------+
6 rows in set (0.02 sec)
mysql>
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我之前也遇到你这样的问题, 如果打算用一条SQl查询某个节点下面的所有叶子节点话,需要在表的结果设计上做点功夫,比如做类似这样的表结构,
ClassID 表示当前节点 类别ID
ClassName 表示当前节点 类别名称
ParentID 表示当前的父亲节点ID
Parent_Path----------->这个列比较关键 就是记录当前节点到 根节点的整个路径如数据0,1,11,111
这样 你在用Sql语句时候查询时候 ,比如查询ClassID =9的所有子节点,Sql 语句就可以这样写Parent_Path like '%,9,%'
希望对你有帮助
ClassID 表示当前节点 类别ID
ClassName 表示当前节点 类别名称
ParentID 表示当前的父亲节点ID
Parent_Path----------->这个列比较关键 就是记录当前节点到 根节点的整个路径如数据0,1,11,111
这样 你在用Sql语句时候查询时候 ,比如查询ClassID =9的所有子节点,Sql 语句就可以这样写Parent_Path like '%,9,%'
希望对你有帮助
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询