2017-06-16 77 views
1

我正在写一个递归存储过程在MySQL中,将返回多行数据,即为孩子和所有的父母,祖父母等数据。例如,如果我有如下表(“家庭”):MySQL递归过程来选择多行

+---------+------+------------+ 
| Status | Name | ParentName | 
+---------+------+------------+ 
| healthy | A | NULL | 
+---------+------+------------+ 
| healthy | B | NULL | 
+---------+------+------------+ 
| healthy | C |  A  | 
+---------+------+------------+ 
| healthy | D |  C  | 
+---------+------+------------+ 
| healthy | E |  B  | 
+---------+------+------------+ 

,我跑的名字“d”的过程中,它应该返回如下:

+---------+------+------------+ 
| Status | Name | ParentName | 
+---------+------+------------+ 
| healthy | D |  C  | 
+---------+------+------------+ 
| healthy | C |  A  | 
+---------+------+------------+ 
| healthy | A | NULL | 
+---------+------+------------+ 

就目前而言,订货不是很重要,我应该能够在以后弄清楚。还值得注意的是,有些情况下父名称按字母顺序大于子表名,而有些情况下父母按字母顺序小于子表名。我见过这样的解决方案,要求父母比孩子少,但这些对我来说不起作用。如果我有权访问支持CTE的MySQL版本,这将非常容易,但不幸的是这是不可能的。相反,我使用递归存储过程来解决我的问题。我到目前为止的代码如下:

DELIMITER | 

CREATE PROCEDURE getNextLevel(IN parent_name TEXT) 

BEGIN 

    IF parent_name IS NOT NULL 

     SELECT Status, Name, ParentName 
     FROM families 
     WHERE ParentName = parent_name 

     UNION 

     CALL getNextLevel(ParentName); 
     -- This is the line that throws an error 

    END IF; 

END | 
DELIMITER ; 

显然,它不是只是叫我的程序递归这样的(也许我打电话是错误的)一样简单。任何人都可以提供任何我需要在这里做什么的洞察,或者可能是我的问题的替代解决方案?

+0

你不能使用这样的存储过程https://stackoverflow.com/a/1492446/4104224 – Uueerdo

+0

这可能是你正在寻找的:https://stackoverflow.com/questions/5291054/generating-深度为基础的树,从分层数据,在MySQL的,无热膨胀系数/ 5291159#5291159。这个答案是专门执行从MySQL中的分层数据深度递归。 –

回答

0

无需递归...伪代码步骤

  1. 与你想要的最终数据字段创建临时表,再加上一个 “迭代”字段
  2. 集迭代0
  3. 添加将“根节点”的数据复制到临时表中进行迭代。
  4. 递增迭代
  5. 将数据插入到源表中的父表中,其中parent在上次迭代的插入行中的数据。
  6. 如果行插入,转到4;否则停止迭代。
  7. 从临时表中选择的数据(不包括迭代0,除非你想要的“根节点”包括,并且迭代列)
  8. 降临时表

棘手的部分:MySQL的可挑剔有关如何TEMPORARY表被使用,所以你可能实际上需要两个;一个用于累加数据,另一个用于保存当前迭代的数据。你可以使用非临时表,但是你会遇到并发调用这个过程碰撞的问题。