Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [PG]Выборка записей входящих в цепочку каталога, Выборка всех подкаталогов каталога 
V
    Опции темы
linuxoid
  Дата 16.7.2009, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 17.4.2005

Репутация: нет
Всего: нет



Здравствуйте уважаемые коллеги!

У меня такая проблема:

В таблице много записей. У каждой из них есть поле - pid (это id родителя, который так же находится в данной таблице). Обзовем каждую запись каталогом. У главных каталогов pid = 0, т.к. выше никого нет. Каталоги с pid=0 являются родителями для всех остальных каталогов (a.k.a. записей таблицы). Т.е. остальные каталоги - child'ы главных. Причем подкаталогов может быть сколь угодно много. Так вот... к примеру каталог с id = 100 будет содержать pid = 60 (т.е. это child каталога, у которого id = 60, и который находится в этой же таблице). В свою очередь каталог с id = 60 является child'ом каталока с id = 30 (т.к. pid  = 30). У записи с id = 30 parent = 0. Т.е. мы дошли до главного каталога (pid = 0), а все предыдущие былы его child'ами. Получаем такой пройденный путь до главного каталога/parent'а: 100 -> 60 -> 30 -> 0.

К примеру в php я могу написать рекурсивную ф-ию, которая будет до упора подниматься вверх от указанного id каталога и закладывать в массив встретившихся id. Получим путь. Из нашего примера это 100 -> 60 -> 30 -> 0. Т.е. мы поднялись к главному родителю и запомнили все промежуточные id. Далее можно использовать такую ф-ию для текущего пути на сайте и т.д.

Вопрос такой: как реализовать проверку в SQL (работаю в PostgreSQL): я указываю parent'a. Нужно выбрать только те записи, которые являются подкаталогами указанного parent'a (к примеру указан id parent'a = 30). Значит когда будим проходить строку, где id = 100, мы увидим, что у этой строки pid = 60, а у этой строки (id = 60) pid = 30. Bingo. Значит данная строка является одним из подкаталогов, входящих в цепочку подразделов для указанного парента

* Задача усложняется тем, что в одной таблице у меня известна только 1 величина: id в таблице каталогов. По этой известной величине (и значению parent'a, которое так же известно) я должен определить, приведет-ли меня этот id по pid к parent'у, который я указал... Если да, то эта запись из таблицы нам подходит, если нет - пропускаем её.


Надеюсь вопрос понятно изложил. Жду с нетерпением какие-то подсказаньки и практические решения (если таковые имеются). Спасибо!
PM MAIL   Вверх
DimW
Дата 22.7.2009, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 2
Всего: 44



Цитата(linuxoid @  16.7.2009,  21:21 Найти цитируемый пост)
Жду с нетерпением какие-то подсказаньки 

CONNECT BY for PostgreSQL 8.3

PM MAIL ICQ   Вверх
linuxoid
Дата 23.7.2009, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 17.4.2005

Репутация: нет
Всего: нет



Цитата(DimW @ 22.7.2009,  13:22)
Цитата(linuxoid @  16.7.2009,  21:21 Найти цитируемый пост)
Жду с нетерпением какие-то подсказаньки 

CONNECT BY for PostgreSQL 8.3

Благодарствую за информацию. Это хорошая зацепка, с помощью которой я нашел более удачный вариант - универсальный метод работы с иерархическими данными в рамках базы данных (метод с CONNECT BY все-таки не подходит, т.к. нужно патчить Postgres + мне скорее всего понадобится перебираться со всеми кодами на MySQL). В общем если кому интерестно, как обойти проблему работы с рекурсией вот ссылка: http://dev.e-taller.net/dbtree/ (чтобы разобраться почитайте 0599-1.pdf).

Но на самом деле в случае с моей проблемой я сделал все проще (за счет чего мои запросы теперь ускорились в разы, т.к. я больше не смешиваю их с функциями PHP для рекурсии). Я просто создал для той самой таблицы другую вспомогательную таблицу - chain_nodes, в которой сделал поля id, ref_table_id (таблица, где я храню id каталога), node_id (перечисляем все id родителей). При добавлении новой записи я теперь просто записываю все узлы до главного каталога в специальную таблицу (chain_nodes), за счет чего удалось добиться хорошей скорости. Просто выбираю те записи, у которых поле id_каталога входит в подкаталоги каталога, который я укажу. Т.е. идет выборка из chain_nodes, где для такой-то записи фигурирует id главного каталога (проблем нет, т.к. я не обновляю и не перетаскиваю никуда эти подкаталоги. Т.е. они всегда на месте и id не меняются).

Это сообщение отредактировал(а) linuxoid - 23.7.2009, 12:47
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PostgreSQL | Следующая тема »


 




[ Время генерации скрипта: 0.0387 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.