2014-12-20 2 views
1

Я хочу получить путь от узла к корню дерева. Это мое дерево, например:Получить корневой путь дерева с чистым MySQL

id | name | parent_id 
------------------------------ 
1 | mike | 0 
2 | danny | 1 
3 | peter | 1 
4 | clark | 2 
5 | lily | 1 
6 | stefan | 3 
7 | simon | 3 
8 | boby | 1 
9 | john | 4 
10 | elly | 4 

я пишу АЛГОРИТМ с PHP и MySQL, но это медленно

public function GetRootPath($a_id) { 
    $root=""; 
    $results=""; 
    while(1==1){ 
     $result = DB::select("SELECT id, parent_id FROM users WHERE id=$a_id"); 
     if($result[0]->refr!=0) { 
       if($root==""){ 
        $root=$result[0]->parent_id; 
       } 
       else { 
        $root=$result[0]->parent_id.'.'.$root; 
       } 
      $a_id=$result[0]->parent_id; 
     } 
     else { 
      break; 
     } 
    } 
    return $root; 
} 

Как это могло быть написано в чистом MySQL? Я не очень разбираюсь в процедурах и функциях MySQL.

+0

Может переключиться на вложенный набор – Strawberry

+0

вложенной набор хороша для дерев с фиксированной глубиной, шахты очень динамичны (реферальная система). – vinsa

+0

Почему вложенный набор хорош для деревьев с фиксированной глубиной? Я бы подумал, что это правда!!!?! – Strawberry

ответ

1

Я думаю, что хранимые процедуры могут работать:

DELIMITER $$ 

DROP PROCEDURE IF EXISTS get_root; 
CREATE PROCEDURE get_root(
    IN parentID INT, 
    OUT rootID INT 
) 

BEGIN 
    SELECT parent_id FROM tree WHERE id = parentID INTO rootID; 

    IF rootID = 0 
     THEN SET rootID = parentID; 
    ELSE 
     CALL get_root(rootID, rootID); 
    END IF; 

END$$ 
DELIMITER ; 

SET @@GLOBAL.max_sp_recursion_depth = 255; 
SET @@session.max_sp_recursion_depth = 255; 

CALL get_root(4, @rootID); 
SELECT @rootID; 
+0

Он работает с некоторыми исправлениями, 'DROP PROCEDURE IF EXISTS get_root;' должен быть до 'DELIMITER $$', этот язык MySQL является сукой. Один вопрос: почему вы устанавливаете @@ GLOBAL и @@ session max_sp_recursion_depth, в чем разница, недостаточно ли @ @ session? – vinsa

+0

Правда, когда я увидел ваш вопрос, я не знал ответа, но мне кажется настолько интересным, что я пытался его решить. Итак, выполняя некоторые исследования, у меня есть этот ответ. Это правда, что с @@ session может быть достаточно, но я предполагаю, что тогда эта процедура будет работать только на одном сеансе. Если вы хотите называть его на любом сеансе, я думаю, вам следует использовать @@ GLOBAL – Noogic

Смежные вопросы