Как создать древовидный вид из этого набора результатов на основе алгоритма обхода дерева?

У меня есть эта таблица:

CREATE TABLE `categories` ( `id` int(11) NOT NULL auto_increment, `category_id` int(11) default NULL, `root_id` int(11) default NULL, `name` varchar(100) collate utf8_unicode_ci NOT NULL, `lft` int(11) NOT NULL, `rht` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `category_id` (`category_id`), KEY `lft` (`lft`,`rht`), KEY `root_id` (`root_id`) ) 

Исходя из этого вопроса: Получение измененной модели обхода дерева предзаказов (вложенный набор) в <ul>

Разница в том, что у меня много деревьев в одной таблице. Каждая строка имеет внешний ключ, представляющий ее родительский элемент и его главный родитель: category_id и root_id. Также у меня есть поля lft и rht на основе этого примера: http://articles.sitepoint.com/article/hierarchical-data-database/2

На основе этих строк:

 INSERT INTO `categories` VALUES(1, NULL, NULL, 'Fruits', 1, 14); INSERT INTO `categories` VALUES(2, 1, 1, 'Apple', 2, 3); INSERT INTO `categories` VALUES(3, 1, 1, 'Orange', 4, 9); INSERT INTO `categories` VALUES(4, 3, 1, 'Orange Type 1', 5, 6); INSERT INTO `categories` VALUES(5, 3, 1, 'Orange Type 2', 7, 8); INSERT INTO `categories` VALUES(6, 1, 1, 'Pear', 10, 11); INSERT INTO `categories` VALUES(7, 1, 1, 'Banana', 12, 13); INSERT INTO `categories` VALUES(8, NULL, NULL, 'Eletronics', 1, 14); INSERT INTO `categories` VALUES(9, 8, 8, 'Cell Phones', 2, 3); INSERT INTO `categories` VALUES(10, 8, 8, 'Computers', 4, 9); INSERT INTO `categories` VALUES(11, 10, 8, 'PC', 5, 6); INSERT INTO `categories` VALUES(12, 10, 8, 'MAC', 7, 8); INSERT INTO `categories` VALUES(13, 8, 8, 'Printers', 10, 11); INSERT INTO `categories` VALUES(14, 8, 8, 'Cameras', 12, 13); 

Как я могу создать упорядоченный список, представляющий это дерево?

С помощью sql ниже:

 SELECT c. * , (COUNT( p.id ) -1) AS depth FROM `categorias` AS p CROSS JOIN categories AS c WHERE ( c.lft BETWEEN p.lft AND p.rht ) GROUP BY c.id ORDER BY c.lft; 

Я получил этот результат:

alt text

Как вы можете видеть, мне нужно также заказать root_id, чтобы я мог сгенерировать правильное дерево.

Кроме того, после получения дерева, есть ли способ упорядочить каждый узел по имени?

Solutions Collecting From Web of "Как создать древовидный вид из этого набора результатов на основе алгоритма обхода дерева?"

Как вы можете видеть, мне нужно также заказать root_id, чтобы я мог сгенерировать правильное дерево.

При построении модели вложенного дерева никогда не делайте дубликатов на rgt и rgt . Фактически, вы должны объявить их уникальными.

В вашей модели данных наборы для категорий 1 и 8 перекрываются. Скажем, от 1 до 14 используются как для пунктов 1 и 8 .

Замените их следующими значениями:

 INSERT INTO `categories` VALUES(1, NULL, NULL, 'Fruits', 1, 14); INSERT INTO `categories` VALUES(2, 1, 1, 'Apple', 2, 3); INSERT INTO `categories` VALUES(3, 1, 1, 'Orange', 4, 9); INSERT INTO `categories` VALUES(4, 3, 1, 'Orange Type 1', 5, 6); INSERT INTO `categories` VALUES(5, 3, 1, 'Orange Type 2', 7, 8); INSERT INTO `categories` VALUES(6, 1, 1, 'Pear', 10, 11); INSERT INTO `categories` VALUES(7, 1, 1, 'Banana', 12, 13); INSERT INTO `categories` VALUES(8, NULL, NULL, 'Eletronics', 15, 29); INSERT INTO `categories` VALUES(9, 8, 8, 'Cell Phones', 16, 17); INSERT INTO `categories` VALUES(10, 8, 8, 'Computers', 19, 24); INSERT INTO `categories` VALUES(11, 10, 8, 'PC', 20, 21); INSERT INTO `categories` VALUES(12, 10, 8, 'MAC', 22, 23); INSERT INTO `categories` VALUES(13, 8, 8, 'Printers', 25, 26); INSERT INTO `categories` VALUES(14, 8, 8, 'Cameras', 27, 28); 

Теперь вам не нужно заказывать root_id .

Кроме того, после получения дерева, есть ли способ упорядочить каждый узел по имени?

Нет простого способа, если вы не введете узлы в порядке имен с самого начала. Братья и сестры с большим name должны иметь больше rgt и rgt :

 INSERT INTO `categories` VALUES(1, NULL, NULL, 'Fruits', 1, 14); INSERT INTO `categories` VALUES(2, 1, 1, 'Apple', 2, 3); INSERT INTO `categories` VALUES(7, 1, 1, 'Banana', 4, 5); INSERT INTO `categories` VALUES(3, 1, 1, 'Orange', 6, 11); INSERT INTO `categories` VALUES(4, 3, 1, 'Orange Type 1', 7, 8); INSERT INTO `categories` VALUES(5, 3, 1, 'Orange Type 2', 9, 10); INSERT INTO `categories` VALUES(6, 1, 1, 'Pear', 12, 13); 

Вложенное дерево может иметь только один неявный порядок.

Существует также способ запросить список смежности в MySQL :

  • Иерархические запросы в MySQL

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

Вы также можете прочитать эту статью:

  • Список привязанностей к вложенным наборам: MySQL

который показывает, как лучше хранить и запрашивать вложенные наборы.

Я понял.

Все, что вам нужно сделать, это установить root_id на верхних родителей, чтобы вы могли правильно выполнить ORDER BY.

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

 SELECT c . * , count( p.id ) AS depth FROM `categories` c CROSS JOIN categories p WHERE ( c.lft BETWEEN p.lft AND p.rht ) AND c.root_id = p.root_id GROUP BY c.id ORDER BY c.root_id, c.lft