Есть таблица elements следующей структуры Adjacency List Model:
id parent index
Где index - это порядок элемента. Нужно одним запросом сформировать путь, получающийся при обходе в глубину. То есть если у нас такой вид:
1 0 1
2 0 2
3 1 1
4 1 2
5 2 1
6 0 3
То выведется 1 3 4 2 5 6
Нужно на чистом mysql без использования php и тд. Заранее спасибо
P.S. Менять в структуре, к сожалению, ничего нельзя
Заранее спасибо
В MySQL нет штатных средств для работы с рекурсивными запросами. Но как известно, если очень хочется, то можно (хотя выглядит это жутковато и оптимизации по скорости это не поддается):
select id,path
from (
select @path:=if(@id!=id,`index`,
coalesce(
(select concat(`index`,'/',@path)
from Tree1 where id=@pid)
,@path)
) path,
@pid:=if(@id!=id,parent,
(select parent from Tree1 N
where id=@pid)
),
@id:=id id, N
from Tree1 T,
(select @n:=@n+1 N
from Tree1,(select @n:=0) N limit 3) Seq,
(select @id:=0,@path:='') X
order by id, N
) X
where N=3
order by path
Так как ни рекурсии ни циклов в обычном смысле слов нет, то запрос эмулирует рекурсию с помощью эмуляции цикла. В качестве цикла используется склейка с любой таблицей, в которой записей не менее, чем максимально возможный уровень иерархии в дереве. В данном примере используется выборка из той же самой таблицы, явно ограниченная limit 3
(если вложенность дерева больше - число надо соответственно увеличить). Собственно данные из этой таблицы не берутся, а создаются порядковые номера (N
).
После этой склейки у нас в выборке появляется по 3 записи с одним и тем же id. На каждой из них, с помощью переменных, мы получаем id очередной родительской ветки, углубляясь по дереву (так как переменные помнят значения, сформированные в предыдущей строке). Самое главное, что мы тут формируем это путь к данной записи в виде индексов сортировки (если index может быть более 9 то для правильной сортировки надо выравнивать его в пути до одинаковой длины с помощью lpad()
)
В какой то момент записи родителей заканчиваются, мы дошли до корня дерева, тогда подзапрос индекса родителя возвращает NULL и при этом с помощью coalesce мы сохраняем ранее сформированный путь. Таким образом в последней записи нашего "цикла" у нас гарантированно будет полный путь до данного листа дерева. Нам остается только убрать из выборки рабочие строки цикла с частично сформированными путями, т.е. выбрать только последние строки (where N=3
) и отсортировать по пути индексов.
Чтобы вывести полный путь в одном запросе нужно использовать Nested Set Model. (Полная информация по ссылке)
Для построения пути можно использовать хранимую функцию. При процедурном языке мы можем начать в нижней части дерева и перебирать вверх, чтобы вернуть полное дерево или единственный путь.
https://web.archive.org/web/20110606032941/http://dev.mysql.com/tech-resources/articles/hierarchical-data.html
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
ЗдравствуйтеЗадание такое: в базе должно храниться не более 12 записей
Всем приветДелаю дэскттопное приложение на виндоус 10 на старой библиотеке SWING
Здравствуйте! Нужно создать небольшое CMS, только пока не могу понять все аспектыПонимаю что можно создать панель администратора и через него...