Подтвердить что ты не робот

Как получить структурированный результат с помощью вложенного набора в MySQL и PHP?

На глубине нет ограничений.

Как получить структурированную ветвь или даже цельное дерево?

Определение отсюда: Управление иерархическими данными в MySQL

4b9b3361

Ответ 1

Я не уверен, что это то, о чем вы просите, но стоит отметить, что вы можете получить все дерево, одну строку на каждый путь, каждый путь в виде строки, как следует из чисто MySQL, используя GROUP_CONCAT и расширение на примере "Получение одного пути" из http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

SELECT 
  GROUP_CONCAT(parent.name ORDER BY parent.lft ASC SEPARATOR '|') 
FROM nested_category AS node
     CROSS JOIN nested_category AS parent 
WHERE 
  node.lft BETWEEN parent.lft AND parent.rgt 
GROUP by node.id 
ORDER BY node.lft;

Это выведет пути для каждого node в дереве.

Обратите внимание, что nested_category AS node CROSS JOIN nested_category AS parent эквивалентно nested_category AS node, nested_category AS parent.

Это использует строку '|' как разделитель, если вы хотите взорвать это в массив элементов пути, и вы знаете там строку, которая не в ваших данных, вы могли бы указать это вместо.

Ответ 2

Я использую аналогичный, но не совсем тот же подход, который также сохраняет ссылку на родителя в дочернем элементе; это упрощает построение древовидной структуры из данных. Если это полезно, я могу опубликовать код для извлечения данных в дерево в PHP.

@Marc, описанная структура данных необязательно для выполнения операций set; он просто упрощает работу со структурой. Если вы хотите получить все дерево данных, и каждая запись просто хранит указатель на родительскую запись, тогда вам нужно рекурсивно запросить базу данных, чтобы получить полное дерево данных. Если вы используете описанный там подход, вы можете извлечь весь набор в одном запросе.

Изменить: здесь код, который строит древовидную структуру, если вы поддерживаете родительскую ссылку child → parent, а также материал lft/right. Я предпочитаю делать это, потому что на самом деле это происходит быстрее, если вы хотите получить только прямые потомки одного уровня дерева.

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

  • Закажите свой запрос с помощью "lft ASC", таким образом вы всегда будете обрабатывать родительский node перед его дочерними элементами.
  • Сохраните ссылку на каждый node по ID; таким образом, любой дочерний элемент этого node может легко найти его и добавить к родительскому.
  • Повторяйте результаты, храните ссылки для каждого по идентификатору (как указано выше) и добавьте этот node к дочерним элементам его родителя.

В любом случае, здесь код -

<?php
$children = mysql_query('SELECT * FROM nested_category ORDER BY lft ASC');

/* Get the first child; because the query was ordered by lft ASC, this is
   the "root" of the tree */
$child          = mysql_fetch_object($children);
$root           = new StdClass;
$root->id       = $child->folderID;
$root->children = array();
/* Store a reference to the object by the id, so that children can add
   themselves to it when we come across them */
$objects        = array($root->id => $root);

/* Build a tree structure */
while ($child = mysql_fetch_object($children)) {
    /* Create a new wrapper for the data */
    $obj           = new StdClass;
    $obj->id       = $child->id;
    $obj->children = array();
    /* Append the child to the parent children */
    $parent = $objects[$child->parent];
    $parent->children[] = $obj;
    $objects[$obj->id] = $obj;
}   

Ответ 3

Даже если структура данных на стороне mysql несколько экзотична, данные все равно извлекаются с использованием обычных методов запросов. Выполните соответствующий запрос выбора, зациклируйте результаты и введите его в массив PHP. Хотя я не знаю, почему вы захотите, так как было бы намного сложнее выполнять заданные операции в PHP, чем в MySQL.

Ответ 4

Посмотрев на вашу ссылку, я сделаю это с помощью Left Joins. Посмотрите пример получения полного дерева.

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4 FROM category AS t1 LEFT JOIN category AS t2 ON t2.parent = t1.category_id LEFT JOIN category AS t3 ON t3.parent = t2.category_id LEFT JOIN category AS t4 ON t4.parent = t3.category_id WHERE t1.name = 'ELECTRONICS';

Вам нужен LEFT JOIN для каждого иерархического уровня, который вы хотите включить. Затем результат может быть проанализирован php на любую желаемую структуру данных. Просто проигнорируйте результаты NULL.

| ELECTRONICS | TELEVISIONS | TUBE | NULL |

| ELECTRONICS | TELEVISIONS | LCD | NULL |

| ELECTRONICS | TELEVISIONS | PLASMA | NULL |

| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |

| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS | NULL |

| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL |

Если у вас есть глубокая структура, это будет хуже, потому что MySQL Joins нужно долгое время выполнять, когда нужно соединить множество таблиц.

Надеюсь, я не понял ваш вопрос неправильно.

Ответ 5

Я должен сообщить вам о методе, с помощью которого вы можете работать с древовидными структурами, используя php.. без рекурсивного. Я думаю, что вы очень хорошо знакомы со стандартной библиотекой php (SPL). Вы можете использовать Итераторы для вашего вопроса.

http://www.php.net/~helly/php/ext/spl/

вот ссылка для документации для SPL. вот несколько решений для вашего примера выше ссылки Mysql: - Просто извлекая свой массив из таблицы, вы можете работать с ними и отображать в качестве предварительного

Для: - модели списка смежности

Вы можете использовать "RecursiveIteratorIterator", который покажет все результаты, включая все дочерние элементы.

Если вы хотите показать только дочерние элементы. вы можете использовать "ParentIterator"