Получать результаты из базы данных MySQL рекурсивно - PullRequest
0 голосов
/ 16 января 2012

Рассмотрим следующее:

Table - id, parentid

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

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

Тогда для parentid = 1 таблица выдаст идентификаторы 2, 3, 4 и 5.

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

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

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

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

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

Ответы [ 3 ]

0 голосов
/ 16 января 2012

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

$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 голосов
/ 12 февраля 2013

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

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;

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

0 голосов
/ 16 января 2012

не за один шаг.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...