当前位置:Gxlcms > mysql > MySQL关于递归的一个问题

MySQL关于递归的一个问题

时间:2021-07-01 10:21:17 帮助过:3人阅读

这篇文章主要介绍了MySQL之递归小问题,需要的朋友可以参考下

mysql本身不支持递归语法,但可通过自连接变相实现一些简单的递归

  1. --递归小方法:临时表和普通表的不同方法
  2. --这题使用的是2次临时表查询父节点的递归
  3. drop table if exists test;
  4. create table test(
  5. id varchar(100),
  6. name varchar(20),
  7. parentid varchar(100)
  8. );
  9. insert test select
  10. '13ed38f1-3c24-dd81-492f-673686dff0f3', '大学教师', '37e2ea0a-1c31-3412-455a-5e60b8395f7d' union all select
  11. '1ce203ac-ee34-b902-6c10-c806f0f52876','小学教师', '37e2ea0a-1c31-3412-455a-5e60b8395f7d' union all select
  12. '37e2ea0a-1c31-3412-455a-5e60b8395f7d', '教师' , null union all select
  13. 'c877b7ea-4ed3-f472-9527-53e1618cb1dc', '高数老师', '13ed38f1-3c24-dd81-492f-673686dff0f3' union all select
  14. 'ce50a471-2955-00fa-2fb7-198f6b45b1bd', '中学教师', '37e2ea0a-1c31-3412-455a-5e60b8395f7d';
  15. delimiter $$
  16. create procedure usp_ser(in idd varchar(100))
  17. begin
  18. declare lev int;
  19. set lev=1;
  20. drop table if exists tmp1;
  21. drop table if exists tmp2;
  22. CREATE TEMPORARY TABLE tmp1(id varchar(100),name varchar(20),parentid varchar(100),levv int);
  23. CREATE TEMPORARY TABLE tmp2(pid varchar(100));
  24. insert tmp2 select parentid from test where id=idd;
  25. insert tmp1 select t.* , lev from test t join tmp2 a on t.id=a.pid;
  26. while exists(select 1 from tmp2 )
  27. do
  28. truncate tmp2;
  29. set lev=lev+1;
  30. insert tmp2 select t.id from test t join tmp1 a on t.id=a.parentid and a.levv=lev-1;
  31. insert tmp1 select t.*,lev from test t join tmp2 a on t.id=a.pid;
  32. end while ;
  33. select id,name,parentid from tmp1;
  34. end;
  35. $$
  36. delimiter ;
  37. call usp_ser('c877b7ea-4ed3-f472-9527-53e1618cb1dc');
  38. +--------------------------------------+----------+--------------------------------------+
  39. | id | name | parentid |
  40. +--------------------------------------+----------+--------------------------------------+
  41. | 13ed38f1-3c24-dd81-492f-673686dff0f3 | 大学教师 | 37e2ea0a-1c31-3412-455a-5e60b8395f7d |
  42. | 37e2ea0a-1c31-3412-455a-5e60b8395f7d | 教师 | NULL |
  43. +--------------------------------------+----------+--------------------------------------+
  44. call usp_ser('13ed38f1-3c24-dd81-492f-673686dff0f3');
  45. +--------------------------------------+------+----------+
  46. | id | name | parentid |
  47. +--------------------------------------+------+----------+
  48. | 37e2ea0a-1c31-3412-455a-5e60b8395f7d | 教师 | NULL |
  49. +--------------------------------------+------+----------+
  50. call usp_ser('37e2ea0a-1c31-3412-455a-5e60b8395f7d');
  51. Empty set (0.02 sec)

上面的方法因为由于MySQL中不允许在同一语句中对临时表多次引用,所以用2次临时表
下面给个一次性用普通表完成的 查询子节点的递归查询

核心代码

  1. drop table if exists test;
  2. create table test(
  3. id INT,
  4. parentid INT
  5. );
  6. insert test select
  7. 1, 0 UNION ALL SELECT
  8. 2, 1 UNION ALL SELECT
  9. 3, 1 UNION ALL SELECT
  10. 4, 0 UNION ALL SELECT
  11. 5, 2 UNION ALL SELECT
  12. 6, 5 UNION ALL SELECT
  13. 7, 3 ;
  14. Go
  15. delimiter $$
  16. create procedure usp_ser(in idd varchar(100))
  17. begin
  18. declare lev int;
  19. set lev=1;
  20. drop table if exists tmp1;
  21. CREATE TABLE tmp1(id INT,parentid INT ,levv INT,ppath VARCHAR(1000));
  22. INSERT tmp1 SELECT *,lev,id FROM test WHERE parentid=idd;
  23. while row_count()>0
  24. do
  25. set lev=lev+1;
  26. insert tmp1 select t.*,lev,concat(a.ppath,t.id) from test t join tmp1 a on t.parentid=a.id AND levv=LEV-1;
  27. end while ;
  28. SELECT * FROM tmp1;
  29. end;
  30. $$
  31. delimiter ;
  32. call usp_ser(0);
  33. /*
  34. +------+----------+------+-------+
  35. | id | parentid | levv | ppath |
  36. +------+----------+------+-------+
  37. | 1 | 0 | 1 | 1 |
  38. | 4 | 0 | 1 | 4 |
  39. | 2 | 1 | 2 | 12 |
  40. | 3 | 1 | 2 | 13 |
  41. | 5 | 2 | 3 | 125 |
  42. | 7 | 3 | 3 | 137 |
  43. | 6 | 5 | 4 | 1256 |
  44. +------+----------+------+-------+*/

以上就是MySQL关于递归的一个问题的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行