Forum Webscript.Ru

Общие => Базы данных => Тема начата: Mrh от 11 Марта 2002, 21:41:41

Название: Запрос запроса запроса...
Отправлено: Mrh от 11 Марта 2002, 21:41:41
Казалась бы простая задача.
База:
ID, Parent_ID, Name

Это таблица с деревом каталогов. Родитель наивысшего уровня имеет Parent_ID = 0 соответственно... Глубина - любая.

Нужно "развернуть" полную структуру каталогов, к примеру:

\\n";
while (list ($ID_Start,$Name) = MySQL_Fetch_Row ($sectResult)):
    echo "
Название: Запрос запроса запроса...
Отправлено: Макс от 12 Марта 2002, 00:43:05
Почему вставка бесконечная, она ведь равна количеству разделов в таблице.
Цитировать
Казалась бы простая задача.
Для мускуля дерево - задача не такая уж простая (ИМХО).
Первое что приходит в голову - примерно так:
1.Формируешь SQL-запрос так, что бы сразу у тебя все эаписи были в необходимом порядке. (ID и ParentID для этого недостаточно ИМХО).
2. Собираешь в массив строки, к которым может быть присоединена текущая строка (его постоянно прийдется менять).
К примеру перед обработкой строки N6 твоего примера ("Без глаз") в массиве должны быть три строки (Рыбы | Глубоководные | В полушубке ) а после ее обработки в массиве уже должно быть (Рыбы | Глубоководные | без глаз )

Короче, если ты ничего не понял и если никто ничего более понятного не предложит - пиши, буду разжевывать (а то сам понимаю, а популярно объяснить - проблема) :(.
Название: Запрос запроса запроса...
Отправлено: Боря Елкин от 12 Марта 2002, 10:10:11
Если дерево, то это рекурсия. Я уже приводил пример обхода http://forums.webscript.ru/showthread.php?s=&postid=17691#post17691 каталога, сейчас попробуем адаптировать к обходу дерева на mysql.

PHP не знаю, нарисую смесь Perl и ПХП.

sub readdirs #читаем дерево каталога
{

$ID_Start=shift;
$In_Name=shift;
my $ret;
$sectQuery = "SELECT ID,Name FROM section WHERE Parent_ID = \'$ID_Start\'";
$sectResult = MySQL_Query ($sectQuery);
return if !$sectResult;

while (list ($ID_Start,$Name) = MySQL_Fetch_Row ($sectResult)){
    $ret.="
Название: Запрос запроса запроса...
Отправлено: Макс от 12 Марта 2002, 16:15:40
Цитировать
Если дерево, то это рекурсия.
Не обязательно.
Можно и одним select-ом дерево вытаскивать. На phpclub мне посоветовали алгоритм "Nested Sets" (вроде так называется) но я его пока не использовал и не разбирался.
В фидо как-то один парень предложил такой алгоритм:
Ввести в таблицу поле (назову его Number) и это поле будет порядковым номером данного элемента в дереве. И сортируя по number получаем на выходе дерево. А при вставке нового элемента в середину дерева все элементы которые будут ниже его изменяют свой number на +1.

Недостаток - тормоза при добавлении элемента в дерево. У меня получилось 2-4 запроса к БД при добавлении элемента.
Название: Запрос запроса запроса...
Отправлено: Боря Елкин от 12 Марта 2002, 16:44:51
ОК, тебе лучше знать, я всего лишь предложил тебе рабочий вариант решения.
Название: Запрос запроса запроса...
Отправлено: Britva от 12 Марта 2002, 18:10:21

function get_categories($selected, $catID, $catName, &$cats){
global $t_category;
$qc = mysql_query("select cid, name, parent from $t_category where parent=\'$catID\' order by name asc");

while($rc = mysql_fetch_array($qc)){
$cats .= "\\n";

$rp = $catName . eregi_replace("_", " ", $rc["name"]);
$rp .= " » ";

get_categories($selected, $rc["cid"], $rp, $cats);
}
}
?>


потом просто вызываешь эту функцию
get_categories($category, 0, "", $categories);
print $categories;
Название: Запрос запроса запроса...
Отправлено: Макс от 13 Марта 2002, 00:00:22
Britva
Цитировать
$cats .= eregi_replace("_", " ", $rc["name"]);

здесь лучше str_replace() использовать
Название: Запрос запроса запроса...
Отправлено: Britva от 13 Марта 2002, 00:18:33
Цитировать
здесь лучше str_replace() использовать

Ага, быстрей работает, просто давно писалось, так пока и не изменил
Название: Запрос запроса запроса...
Отправлено: Mrh от 13 Марта 2002, 01:07:46
Britva, мое невероятное СПАСИБО :)

Все отработало в идеале, но все-таки function(function(function... - это как с горки без тормозов в туман :)

get_categories($category, 0, "", $cats);
print $cats;


function get_categories($selected, $catID, $catName, &$cats){
    global $t_category;
    $qc = mysql_query("select ID, Name, Parent from section where parent=\'$catID\'");
    while($rc = mysql_fetch_array($qc)){
        $cats .= "\\n";
        $rp = $catName . str_replace("_", " ", $rc["Name"]);
        $rp .= " » ";
        get_categories($selected, $rc["ID"], $rp, $cats);
    }
}

P.S. Модератору: это стоит занести в FAQ, я три вопроса получил, - "ну как получилось..? а как все-таки ты сделал...?".