Ситуация:
У меня есть таблица каталогов mysql. Каждый каталог имеет родительский каталог (хранится как parentID), вплоть до того момента, когда корневой каталог имеет parentID 0.
например:.
rowID: 1, name: Dir1, parentID: 0 (root directory)
rowID: 2, name: Dir2, parentID: 0 (root directory)
rowID: 3, name: Subdir1, parentID: 1 (lives in "Dir1")
rowID: 4, name: Subdir2, parentID: 1 (lives in "Dir1")
rowID: 5, name: Subdir3, parentID: 3 (lives in "Subdir1", which in turn lives in "Dir1")
rowID: 6, name: Subdir4, parentID: 5 (lives in "Subdir3", which lives in "Subdir1", which lives in "Dir1")
Итак, здесь есть 3 структуры глубины каталога.
Мне нужно создать оператор, который присоединяет любой каталог к его родительскому объекту и продолжает делать это до тех пор, пока последний объединенный каталог не будет иметь parentID из 0 (т.е. нашел корневой каталог). Вы можете думать об этом так, как будто, учитывая любой каталог, вы можете найти корневую папку обратно родительскому.
Я полагаю, что для этого может потребоваться некоторый цикл MySQL, но для жизни я не могу заставить ни один из веб-примеров работать. Я даже не могу получить некоторые примеры для запуска, поскольку в них, похоже, есть какие-то синтаксические ошибки. Может кто-нибудь помочь мне начать?
Я могу принять любой формат результата, который является самым простым и дает лучшую производительность, чтобы сделать это. Либо простой массив номеров строк в правильном порядке (например, 5, 3, 1, 0, указывающий шаги для получения идентификатора 0), либо полную таблицу (лучше всего), которая будет упорядоченным списком строк, которые достигают этого, например,
rowID: 5, name: Subdir3, parentID: 2;
rowID: 3, name: Subdir1, parentID: 1;
rowId: 1, name: Dir1, parentID: 0;
Помогите оценить!
Хорошо, нашел время фактически развернуть простую базу данных с аналогичной структурой, как описано.
Таблица выглядит следующим образом:
CREATE TABLE `t_hierarchy` (
`rowID` INT(11) NULL DEFAULT NULL,
`name` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_general_ci',
`parentID` INT(11) NULL DEFAULT NULL
);
Я в основном вставлял то же самое, что и выше, но использовал значения NULL вместо 0 для root/no parent
То, что я сделал, является довольно загадочным примером из http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/. и просто скорректировал имена столбцов, чтобы они соответствовали моим.
Поскольку это только порождает рекурсивную иерархию, я просто добавил глупое соединение в пример (ad.rowID = qi.id):
SELECT qi.id, qi.parent, ad.rowId, ad.name, level
FROM (
SELECT @r AS id,
(
SELECT @r := parentID
FROM t_hierarchy
WHERE rowID = id
) AS parent,
@l := @l + 1 AS level
FROM (
SELECT @r := 5, -- change this 5 to the directory ID you want to resolve
@l := 0,
@cl := 0
) vars,
t_hierarchy h
WHERE @r <> 0
ORDER BY
level DESC
) qi, t_hierarchy ad
WHERE ad.rowID = qi.id
И это генерирует следующий (желаемый) вывод:
id parent rowId уровень имени
1 NULL 1 Dir1 3
3 1 3 Subdir1 2
5 3 5 Subdir3 1
Уровень - это вспомогательный столбец, который говорит вам, как "глубоко" он должен был решить, чтобы достичь этого. Все, что вам нужно сделать, это изменить "5" рядом с @r: = на идентификатор каталога, из которого вы хотите продолжить итерацию.
Если вы хотите переключить направление (от до нисходящего), просто отсортируйте по столбцу уровня ([...] WHERE ad.rowID = qi.id ORDER BY level ASC)
Надеюсь, это поможет вам.
Изменить: qi.id и ad.rowID являются дубликатами, просто удалите один из них; -)... черт возьми, я ненавижу этот материал иерархии
Ну, может быть, вы не нашли хороший веб-пример, потому что вы использовали неправильный поисковый термин. Описанная проблема отлично вписывается в оракулы CONNECT BY PRIOR и при поиске по mysql-эквивалентам этого утверждения вы находите http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/ довольно быстро.
Поскольку это не так просто (и у меня нет mysql-db, чтобы изнасиловать здесь), чтобы написать этот материал, просто взгляните на приведенные хорошие примеры (вы даже можете сделать это без развернутых функций через http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/.
Если вы по-прежнему не можете повесить их, я, возможно, смогу помочь дома.