Как отображать и правильно указывать древовидную структуру одного узла?

Структура БД выглядит следующим образом:

cat_ID| cat_name | cat_nicename | lft | rgt _________________________________________________ 287 | Wallpapers | wallpapers | 61 | 62 1656 | Gadget | gadget | 63 | 64 1958 | Sms | sms | 65 | 66 2901 | fun | fun | 67 | 68 4419 | Joke | joke | 69 | 70 4775 | health | health | 71 | 72 5098 | Mobile | mobile | 73 | 90 5100 | TV | tv | 91 | 92 5101 | Main | main | 93 | 94 5102 | Nokia | nokia | 76 | 83 5103 | Samsung | samsung | 84 | 87 5104 | Micromax | micromax | 88 | 89 5105 | Nokia Sub 1 | nokiasub1 | 77 | 78 5106 | Nokia Sub 2 | nokiasub2 | 79 | 82 5107 | Nokia Sub 3 | nokiasub3 | 80 | 81 5109 | Galaxy | galaxy | 85 | 86 

Запрос Folloing, который я использую, чтобы получить одну категорию и все ее подкаты:

 $sql = "SELECT n.cat_ID,n.cat_name,n.cat_nicename, (COUNT(*)-1) AS depth FROM " .TBL_CATEGORIES. " AS n, " .TBL_CATEGORIES. " AS p WHERE p.cat_nicename='mobile' AND n.lft BETWEEN p.lft AND p.rgt GROUP BY n.lft ORDER BY n.lft;"; $result = mysql_query($sql); $tree = array(); while ($row = mysql_fetch_assoc($result)) { $tree[] = $row; } function _tab($depth) { $tabs = ''; while ($depth-- > 0) $tabs .= '&nbsp;&nbsp;&nbsp;&nbsp;'; return $tabs; } // bootstrap loop $result = ''; while (!empty($tree)) { $currNode = array_shift($tree); $result .= _tab($currNode['depth']) . $currNode['cat_name'] . $currNode['depth'].'<br />'; } print $result; 

если я не использую p.cat_nicename='mobile' , по приведенному выше коду, древовидная структура отображается идеально, но если я хочу получить только один узел, используя p.cat_nicename='mobile' Вся глубина, которую я получаю, равна '0' поэтому он НЕ помещает никаких &nbsp; и отображение плоского дерева под 'mobile' . Если я запрошу только "mobile" он должен выглядеть так:

 Mobile Nokia Nokia Sub 1 Nokia Sub 2 Nokia Sub 3 Samsung Galaxy Micromax 

поэтому мои вопросы:

  1. Как я могу отобразить Дерево определенного узла?
  2. Как я могу отображать только все корневые категории? no childs no sub, используя один SQL-запрос?

  1. Просмотрев структуру таблицы и запрос, я не думаю, что есть способ выбрать дерево определенного узла без дополнительного подзапроса (возможно, я ошибаюсь, но это единственный способ заставить его работать при тестировании). Чтобы сделать это, я предложил бы добавить дополнительный запрос в предложение FROM , как если бы вы выбирали из 3-го стола. Затем добавьте дополнительное условие BETWEEN в WHERE , чтобы проверить его.

    Что-то вроде этого:

     SELECT n.cat_ID, n.cat_name, n.cat_nicename, COUNT(*)-1 AS depth FROM categories AS n, categories AS p, (SELECT lft, rgt FROM categories WHERE cat_nicename = 'mobile') AS q WHERE n.lft BETWEEN p.lft AND p.rgt AND p.lft BETWEEN q.lft AND q.rgt GROUP BY n.lft ORDER BY n.lft; 

    Используя это, вам нужно будет добавить всю логическую обработку, «какой» узел вы хотите получить дерево в подзапросе. Первые две таблицы ( n и p ) выбираются – как обычно. Это необходимо для получения правильных значений depth . Затем он сравнивает p и q – но q уже ограничен. Итак, как только у вас есть правильные значения depth вы ограничиваете их только теми категориями, которые вы хотите.

  2. Показывать все корневые категории намного проще. Используя ваш запрос, определение «корневой категории» – это значение, которое имеет depth = 0 . Если вы используете предложение MySQL HAVING , вы можете легко проверить его с помощью HAVING depth = 0 . Попробуйте следующее:

     SELECT n.cat_ID, n.cat_name, n.cat_nicename, COUNT(*)-1 AS depth FROM categories AS n, categories AS p WHERE n.lft BETWEEN p.lft AND p.rgt GROUP BY n.lft HAVING depth = 0 ORDER BY n.lft;