2017-06-16 52 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表被使用,所以你可能實際上需要兩個;一個用於累加數據,另一個用於保存當前迭代的數據。你可以使用非臨時表,但是你會遇到併發調用這個過程碰撞的問題。