2017-06-16 10 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のno-ctes/5291159#5291159この回答は、具体的には、MySQLの階層データからの深さに基づく再帰を実行しています。 –

答えて

0

再帰のための必要性無し...擬似コードは

  1. が0
  2. 追加するあなたが望む最終的なデータのためのフィールドを持つ一時テーブル、プラス 「反復」フィールド
  3. セットの反復を作成手順反復のための一時テーブルへの "ルートノード"のデータ。
  4. 増分の繰り返し
  5. 最後の反復の挿入された行の親のソーステーブルからデータを一時テーブルに挿入します。
  6. 行が挿入された場合、goto 4;それ以外の場合は反復を停止します。 MySQLはどの程度細心の注意することができます:一時テーブルから
  7. 選択データ
  8. ドロップ一時テーブル

トリッキーな部分(あなたは、「ルートノード」が含まれ、反復列を使用する場合に限り、反復0を除きます) TEMPORARYテーブルが使用されるため、実際には2つ必要です。 1つはデータを蓄積し、もう1つは現在の反復のデータを保持する。非TEMPORARYテーブルを使用することもできますが、このプロシージャへの同時呼び出しの問題にぶつかります。

関連する問題