Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: дерево каталога одним запросом
 
 автор: Дмитрий Смаль   (27.10.2009 в 21:14)   письмо автору
 
 

Здравствуйте!

есть таблица
id | cat | range | name
1.....0.......10.......главная
2.....1.......10.......категория1
3.....1.........9.......категория2
4.....2.........1.......подкатегория1 для категории1

я вывожу всё дерево вызываю функцию в ней же
function menu_cat_tree ($m,$cat,$i=0) {
    global $a;
    $a = "{$a}   ";
    $result = mysql_query ("SELECT id,name FROM `$m` WHERE cat='$i' ORDER BY range DESC");
    $last=mysql_num_rows($result); $i=0;
    while ($q = mysql_fetch_array ($result)) {
        $a.=':'; $ii=" "; if (strlen($a)>14) $ii = ".. ";
        $selected = $q[id]==$cat ? 'selected':'';
        $echo.= "\n<option value='cat=$q[id]&id=0' $selected>".substr($a, 20)."{$ii}[$q[name]]</option>";
        $i++; if ($last==$i) $a="".substr($a, 0, -1)." ";
        $echo.= menu_cat_tree($m,$cat,$q[id]);
    }
    $a = substr($a, 0, -14);
    return $echo;
}

получается что первый sql-запрос выбирает все верхние категории, второй запрос выбирает все первые подкатегории к первой категории и т.д.
плюс ко всему это сортируется по рейтингу и ставятся отступы во внутренних категориях
в итоге получится
главная
:..категория1
:....подкатегория1 для категории1
:..категория2


интересует 2 вопроса
1. можно ли всё это сделать меньшим количеством запросов?
2. рассмотрим запись "подкатегория1 для категории1" - как одним запросом выбрать её и все её родительские категории?

  Ответить  
 
 автор: Trianon   (27.10.2009 в 21:51)   письмо автору
 
   для: Дмитрий Смаль   (27.10.2009 в 21:14)
 

Nested sets

  Ответить  
 
 автор: Дмитрий Смаль   (28.10.2009 в 12:55)   письмо автору
 
   для: Trianon   (27.10.2009 в 21:51)
 

Спасибо, идея конечно интересная, но смущает что при добавлении нового раздела надо пересчитывать ключи во всех категориях

  Ответить  
 
 автор: Trianon   (28.10.2009 в 15:50)   письмо автору
 
   для: Дмитрий Смаль   (28.10.2009 в 12:55)
 

Для дерева сообщений в форуме я бы такую структуру не предложил.

Так ли уж часто у Вас добавляются разделы?
А подобный пересчет выполняется одним запросом. Относительно легким, поскольку модифицируемые записи размер свой не меняют.

  Ответить  
 
 автор: Дмитрий Смаль   (31.10.2009 в 11:10)   письмо автору
 
   для: Trianon   (27.10.2009 в 21:51)
 

$result = mysql_query ("
    SELECT t1.id,t1.name,t2.id,t2.name,t3.id,t3.name
    FROM category t1,category t2,category t3
    WHERE t1.cat=0 AND t1.id=t2.cat AND t2.id=t3.cat
    ORDER BY t1.range DESC,t2.range DESC,t3.range DESC
");
while ($q = mysql_fetch_array ($result)) {
    if ($q[0]!=$id1) echo "[$q[0]] $q[1]<br />";
    if ($q[2]!=$id2) echo ":.. [$q[2]] $q[3]<br />";
    echo "&nbsp; &nbsp; :.. [$q[4]] $q[5]<br />";
    $id1=$q[0];
    $id2=$q[2];
}

id - ID записи
cat - ID родительской записи
вот такой код получился, но проблема в том что не выводятся те записи, у которых вложенности нету или только один уровень вложенности

  Ответить  
 
 автор: Дмитрий Смаль   (31.10.2009 в 11:47)   письмо автору
 
   для: Trianon   (27.10.2009 в 21:51)
 

$result = mysql_query ("
    SELECT t1.id,t1.name,t2.id,t2.name,t3.id,t3.name
    FROM category t1
    LEFT JOIN category t2 ON t1.id=t2.cat
    LEFT JOIN category t3 ON t2.id=t3.cat
    WHERE t1.cat=0
    ORDER BY t1.range DESC,t2.range DESC,t3.range DESC
");
while ($q = mysql_fetch_array ($result)) {
    if ($q[0]!=$id1)  echo "[$q[0]] $q[1]<br />";
    if (isset($q[2])) {
        if ($q[2]!=$id2)  echo ":.. [$q[2]] $q[3]<br />";
        if (isset($q[4])) echo "&nbsp; &nbsp; :.. [$q[4]] $q[5]<br />";
    }
    $id1=$q[0];
    $id2=$q[2];
}

а вот полностью рабочий код, который одним запросом выводит полное дерево с 3-х уровневой вложеностью

  Ответить  
 
 автор: Trianon   (31.10.2009 в 13:23)   письмо автору
 
   для: Дмитрий Смаль   (31.10.2009 в 11:47)
 

Это все частные случаи. Которые, кстати, крайне неудобно разбирать в цикле.
А когда потребуется 4, 5, 20-й уровень?

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования