Страница 1 из 1
SQL запрос обхода дерева
Добавлено: 2010.12.05, 14:34
mitaichik
Всем привет ))
Есть простая таблица дерева:
id, parent_id, name
Так вот, name указан не везде, и в случае его отсутсвия (пустая строка) нужно взять его у родителя. Если и там его нет - то у родителя родителя, и т.д.
Реально ли реализовать такую штуку одним запросом? И если да - то как )))
P.S. Я знаю, что такое можно реализовать средствами PHP, делая кучу запросов, но интересует именно реализация с пом. MySQL сервера (может используя какие-либо хранимые процедуры, или исчо какие-либо его возможности, я в этом плохо разбираюсь)
Re: SQL запрос обхода дерева
Добавлено: 2010.12.05, 16:04
AbS_
написать процедуру.
Re: SQL запрос обхода дерева
Добавлено: 2010.12.05, 17:39
samdark
Задача вывести всё дерево или один узел? Дерево большое? Сколько узлов?
Re: SQL запрос обхода дерева
Добавлено: 2010.12.05, 23:00
mitaichik
Задача вывести один узел, но если у него не задан параметр name, то взять его у вышестоящего. То что я написал - это для примера. На самом деле это для следующего: В таблице pages есть поля meta_title, meta_description, meta_keywords. Если они у страницы не заданы - их нужно взять у родителей. Если и они не заданны, то берем те что заданы в настройках сайта по умолчанию.
У битрикса такая модель задания meta-тегов, и считаю что она хороша. Вот.
Re: SQL запрос обхода дерева
Добавлено: 2010.12.06, 00:38
samdark
А при сохранении это не решить?
Re: SQL запрос обхода дерева
Добавлено: 2010.12.06, 14:17
zibert02
тут нужен рекурсивный обход, скорее всего уже в самой модели
Re: SQL запрос обхода дерева
Добавлено: 2010.12.06, 23:33
mitallast
Если дерево не слишком часто обновляется, или его можно разбивать на отдельные ветки - например, по ветке комментариев на статью - то можно использовать Nested set дерево.
Тогда саюж можно будет выбрать за один запрос, типа
Код: Выделить всё
select name from tree where root_id = :root_id and left < :left and right > :right and name not null order by left desc limit 1
где :root - текущая ветка, :left и :right - границы текущего нода.
http://www.getinfo.ru/article610.html
http://code.google.com/p/yiiext/source/ ... odel/trees
Re: SQL запрос обхода дерева
Добавлено: 2010.12.07, 00:25
pirrat
mitaichik писал(а):Задача вывести один узел, но если у него не задан параметр name, то взять его у вышестоящего. То что я написал - это для примера. На самом деле это для следующего: В таблице pages есть поля meta_title, meta_description, meta_keywords. Если они у страницы не заданы - их нужно взять у родителей. Если и они не заданны, то берем те что заданы в настройках сайта по умолчанию.
У битрикса такая модель задания meta-тегов, и считаю что она хороша. Вот.
Если у страницы только 2 уровня, то как то так:
Код: Выделить всё
SELECT *, COALESCE(p.`meta_title `, (SELECT `meta_title ` FROM pages as p1 WHERE id=p.pid), (SELECT meta_title FROM settings) ) as meta_title FROM pages as p WHERE id=2
этот запрос делает следующее - выбирает для заданной категории meta_title: первое not null значение из meta_title текущей страницы, её родителя и таблицы настроек.
для большой вложенности, лучше заюзать нестед сетс ну или морочиться с хранимыми процедурами и тд.
и в любом случае, лучше все же пересчитывать при сохранении!
Re: SQL запрос обхода дерева
Добавлено: 2010.12.07, 10:46
Svyatov
Sam Dark писал(а):А при сохранении это не решить?
+1, определять эти значения при каждом запросе страницы - слишком накладная операция. Надо определять и сохранять это на этапе сохранения страницы.
Re: SQL запрос обхода дерева
Добавлено: 2010.12.07, 15:07
mitaichik
+1, определять эти значения при каждом запросе страницы - слишком накладная операция. Надо определять и сохранять это на этапе сохранения страницы.
Да, пожалуй, Вы правы. Так и сделаем.