Страница 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, определять эти значения при каждом запросе страницы - слишком накладная операция. Надо определять и сохранять это на этапе сохранения страницы.
Да, пожалуй, Вы правы. Так и сделаем.