Оптимизация поиска дочерних элементов

Yurik

/dev/null
Оптимизация поиска дочерних элементов

Задача:
есть в таблице дерево "id, pid" (parent id)
есть массив элементов ids
нужно выбрать массив всех дочерних элементов каждого из этих заданных ids

Решение:
PHP:
 function findchildren($_ids){
  foreach ($_ids as $_id) {
   do {
    $_sql="SELECT id FROM table WHERE pid=".$_id;
    $_result=$this->query($_sql, __LINE__, __FILE__);
    while ($_row=mysql_fetch_row($_result)) $_tmp[]=$_id=$_row[0];
   } while (mysql_num_rows($_result)!=0);
  }
  return $_tmp;
 }
Ежу понятно что оно нерациональное т.к. делается M*N запросов, где N - средний уровень вложения, M - изначальное к-во родителей в массиве $ids

Здается мне что можно все это сделать через 1 запрос, в котором будет LEFT JOIN таблицы "на себя" и вместо WHERE pid=N писать WHERE pid IN (a, b, c...) но не могу придумать запроса.
(a, b, c..) - элементы массива ids
 

Yurik

/dev/null
Суда-туда, да был я там.. мед пиво пил
Не то мне нужно.
Вроде tony2001 как-то запрос похожий писал но найти не могу
 

Popoff

popoff.donetsk.ua
Тьфу %) Сорри за глупость %))) Это я по мотивам вот такого сообщения написал %)

Похоже на то, что без nested sets никак.. Можно попытаться сделать несколько left join на самого себя для уменьшения количества запросов... Но тогда в каждой строчке результата будет содержаться путь от родителя к самому нижнему потомку, т.е. сложно будет выбрать потомков, находящихся на этом пути....

Помысли в направлении "как работает select?": выбираются нужные записи из первой таблицы, потом подходящие записи из второй (в нашем случай той же) таблицы.... Похоже на то, что никак ты не выберешь внука за одино соединение таблиц, владея только информацией о родителе и не владея никакой информацией о ребенке....
 

clevel

Новичок
я для себя прикидывал, какую методу в данном вопросе использовать - nested sets или вот такую:
добавляем поле pids(char(255)), где через запятую хранятся список id родителей... Тогда поиск всех детей определенного элемента делается как:
PHP:
if(strlen($pids)>0) $pids.=",";
$pids.=$id;
[sql]
SELECT id
FROM tree_table
WHERE pids LIKE '".$pids."%'
[/sql]
Да, если на это поле индекс поставить, будет вообще хорошо.
Остался на этом варианте, правда такое использование у меня побочное, основное - поиск по номеру элемента список его родителей(как пример, путь до файла).
Сильно не пинайте...
 
Сверху