2013-09-30 6 views
2

У меня есть таблица с идентификатором пользователя, ManagerID следующим образом:Получить всех детей от родителей в MySQL Query

id  manager 
------- ------- 
admin (NULL)  
james admin 
user  james 
workad user 
creator workad 

Теперь я хочу, чтобы все дети (потомки) для одного идентификатора пользователя. Другими словами, для userid james Мне нужны дети пользователь, workad, создатель. Потому что james является главным родителем (предком). Есть ли какой-либо запрос для получения результата, подобного этому в mysql ... Спасибо заранее.

+0

Вам нужно будет написать хранимую процедуру. MySQL не поддерживает рекурсивные запросы. –

+0

я тоже думаю подобный только. Но я пытаюсь написать один запрос. –

+0

Вы можете ** не ** делать это с помощью одного запроса в MySQL. –

ответ

3

Для этого вам необходимо иметь хранимую функцию:

DELIMITER $$ 

DROP FUNCTION IF EXISTS `junk`.`GetFamilyTree` $$ 
CREATE FUNCTION `GetFamilyTree` (GivenID VARCHAR(1024)) RETURNS varchar(1024) CHARSET latin1 
DETERMINISTIC 
BEGIN 

    DECLARE rv,q,queue,queue_children,front_id VARCHAR(1024); 
    DECLARE queue_length,pos INT; 

    SET rv = ''; 
    SET queue = GivenID; 
    SET queue_length = 1; 

    WHILE queue_length > 0 DO 
     SET front_id = queue; 
     IF queue_length = 1 THEN 
      SET queue = ''; 
     ELSE 
      SET pos = LOCATE(',',queue) + 1; 
      SET q = SUBSTR(queue,pos); 
      SET queue = q; 
     END IF; 
     SET queue_length = queue_length - 1; 

     SELECT IFNULL(qc,'') INTO queue_children 
     FROM (SELECT GROUP_CONCAT(id) qc 
     FROM Table1 WHERE manager = front_id) A; 

     IF LENGTH(queue_children) = 0 THEN 
      IF LENGTH(queue) = 0 THEN 
       SET queue_length = 0; 
      END IF; 
     ELSE 
      IF LENGTH(rv) = 0 THEN 
       SET rv = queue_children; 
      ELSE 
       SET rv = CONCAT(rv,',',queue_children); 
      END IF; 
      IF LENGTH(queue) = 0 THEN 
       SET queue = queue_children; 
      ELSE 
       SET queue = CONCAT(queue,',',queue_children); 
      END IF; 
      SET queue_length = LENGTH(queue) - LENGTH(REPLACE(queue,',','')) + 1; 
     END IF; 
    END WHILE; 

    RETURN rv; 
END $$ 

Тогда вы можете назвать как:

SELECT `id`, `manager`,GetFamilyTree(`id`) as children 
from Table1; 

Вы можете иметь фильтры, а также:

SELECT `id`, `manager`,GetFamilyTree(`id`) as children 
from Table1 where `id` = 'james'; 

SAMPLE FIDDLE

+0

Процедура работает, но я поиск есть в любом случае для одного запроса –

+0

Невозможно в mysql :( –

+0

Кто-нибудь знает, возможно ли это в HQL? –

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