2012-01-16 6 views
0

Рассмотрим следующий пример:Получить результаты из базы данных MySQL рекурсивно

Table - id, parentid

То, что я хотел бы сделать, это я хотел бы, чтобы вытащить все дети (не только прямые дети, но все их, т.е. детей детей детей и т. д.) конкретного родителя.

Так скажем, таблица содержит следующую строку: (2, 1), (3, 1), (4, 2), (5, 4)

Тогда для ParentID = 1, таблица будет возвращать идентификаторы 2, 3, 4 и 5.

Возможно ли это?

Если нет (и я думаю, что это действительно невозможно), каковы мои варианты?

Я действительно не хочу, чтобы использовать десятки запросов ...

P.S. Я не могу изменить структуру базы данных.

Кроме того, поскольку в таблице могут быть сотни тысяч записей, я могу вытащить их все и сделать все, используя PHP вместо этого.

ответ

0

Это может помочь:

$parentId = 1; // the parent id 
$arrAllChild = Array(); // array that will store all children 
while (true) { 
    $arrChild = Array(); // array for storing children in this iteration 
    $q = 'SELECT `id` FROM `table` WHERE `parentid` IN (' . $parentId . ')'; 
    $rs = mysql_query ($q); 
    while ($r = mysql_fetch_assoc($rs)) { 
     $arrChild[] = $r['id']; 
     $arrAllChild[] = $r['id']; 
    } 
    if (empty($arrChild)) { // break if no more children found 
     break; 
    } 
    $parentId = implode(',', $arrChild); // generate comma-separated string of all children and execute the query again 
} 
print_r($arrAllChild); 

Вы можете также использовать рекурсию, чтобы сделать это, но я думаю, что выше будет нуждаться в меньшем количестве итераций.

Надеюсь, это поможет!

EDIT - Я забыл упомянуть, что вы можете реализовать ту же логику в хранимой процедуре MySQL, за исключением того, что вы не можете использовать массивы. Приведенный выше пример реализован в PHP, как вы, возможно, уже догадались

+0

Я думаю, нет лучшего решения, спасибо! – Lior

0

нет в одном шаге.

Я сделал рекурсивные запросы в MySQL с помощью PHP ... перекручивание через один уровень, собирая данные, изменения запроса использовать результаты привели обратно в последней итерации, снова выполнив запрос и т.д.

Mysql не очень дружелюбен к подобным вещам. MSSQL, Oracle или PostgreSQL поддерживают его в формате сингулярных запросов.

0

Вот запрос, я написал только сейчас для подобной задачи:

select if(e.id is not null, e.id, if(d.id is not null, d.id, if(c.id is not null, c.id, if(b.id is not null, b.id, a.id)))) as ID 
from groups a 
left join groups b on b.parent = a.id 
left join groups c on c.parent = b.id 
left join groups d on d.parent = c.id 
left join groups e on e.parent = d.id 
where a.parent = SOMETOPLEVELPARENTIDHERE; 

Такой подход не имеет фиксированного предела глубины. По моим собственным данным, я знаю, что он охватывает не более пяти уровней глубины. Если глубина достаточно стабильна, вы можете разместить некоторый рост, просто добавив больше левых объединений. Кроме того, не знаете, как будет выполняться запрос сотнями тысяч записей.

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