Форум: "Базы";
Текущий архив: 2002.08.05;
Скачать: [xml.tar.bz2];
ВнизПоиск по дереву записанному в таблице БД Найти похожие ветки
← →
Griffin (2002-07-11 16:14) [0]У меня есть таблица, в ней содержатся узлы дерева (номера людей и их счета).
Иногда необходимо прогнать следующую вещь: просуммировать счета потомков по всем записям. Приходится по каждому узлу делать свой SQL-запрос, получать номера потомков первого поколения, потом делать по всем ним запросы, получать потомков второго и т.д. Узлов в дереве около 3000. И ветвление хорошее. Поэтому эта штука задумывается минут на 10-15. Я уже голову сломал соображая, как оптимизировать эту конструкцию. Хочется в итоге, чтобы она думала 1-2 минуты, не более. Машинка резвая. Может кто чего подскажет.
← →
still (2002-07-11 16:27) [1]Можно чуть подробнее о структуре базы?
← →
Vogus (2002-07-11 16:42) [2]
while not Table.Eof do
begin
if TablePARENTID.AsInteger <> -1 then
Proc(TablePARENTID.AsInteger, TableACOUNTSUM.AsCurrency);
Table.Next;
end;
procedure Proc(PARENTID: Integer; S: Currency);
begin
if Table2.Locate("PARENTID",PARENTID,[]) then
Table2S.AsCurrency := Table2S.AsCurrency + S
else
Table2.AppendRecord([PARENTID, S]);
end;
может что-то недопонял - простите!
← →
Griffin (2002-07-11 23:56) [3]--- для STILL
Структура базы не столь важна. Речь об одной таблице. В ней есть поле номера человека, поле номера его предка и поле счета этого человека. Номера таковы, что вся структура в целом может быть записана в виде дерева предок-потомок. Но в таблице-то она линейная. Мне необходимо делать SQL-запросы, чтобы получить номера потомков в каждом конкретном случае. А это очень долго. И я хочу понять, существует ли такой хитрый SQL-запрос, чтобы
как-то обойти эту проблему?
---для VOGUS
Спасибо, подумаем...
← →
jonik pegas (2002-07-12 09:15) [4]SELECT table.* FROM table INNER JOIN table AS table_1 ON table.idp = table1.id
WHERE (((table_1.id)=ид родителя))-все потомки 1 уровня;
SELECT table.*
FROM (table INNER JOIN table AS table_1 ON table.idp = table_1.id) INNER JOIN table AS table_2 ON table_1.idp = table_2.id
WHERE (((table_2.id)=ид родителя))-все потомки 2 уровня;
и т.д
количество запросов равно n+1 уровней вложенности
← →
still (2002-07-12 09:42) [5]1. попробуй добавить индекс по полю parentid
2. такое предложение - ввести в таблицу служебное поле, показывающее уровень вложенности данного узла и создать по нему индекс.
Мне кажется при 3000 записей не должно тормозить.
← →
Griffin (2002-07-12 11:36) [6]--- для JONIK PEGAS
Спасибо. Но это не решает проблем
Я сделал такой запрос
SELECT * FROM Table INNER JOIN Table AS Table_1 ON Table.KOD_UP = Table_1.KOD
WHERE Table.KOD_UP=Table_1.KOD
И, разумеется, получил список ВСЕХ потомков ПРОИЗВОЛЬНОГО УРОВНЯ
А если "WHERE Table.KOD_UP=конкретный код", то и огород городить не надо
Может я чего не понял?
И еще, уровней вложенности, вообще говоря, может быть сколько угодно - это что ж
каждый раз добавлять к запросу INNER JOIN и т.д или может написать процедурку которая сама формирует запрос? Нельзя ли покороче?
И все равно, мне придется в дальнейшем фильтровать полученные N штук запросов для каждого человека.
Все-таки хочется эстетики
Но все равно спасибо. Это уже лучше чем было. Подумаем.
--- для STILL
Спасибо!
Индексы - вещь хорошая, но все равно, лучше просто снизить количество запросов. А вот КАК его снизить - пока вопрос.
Поле показывающее уровень вложенности не пойдет - надо будет перелопачивать всю прогу. Лучше уж INNER JOIN
← →
jonik pegas (2002-07-12 12:49) [7]Верх эстетики-хранимые процедуры на сервере, одной процедурой на сервере можно все извлечь но не для парадокса
А запрос у тебя странный ON Table.KOD_UP = Table_1.KOD
WHERE Table.KOD_UP=Table_1.KOD-зачем два раза повторяешь
← →
Griffin (2002-07-12 21:37) [8]--- для JONIK PEGAS
Это просто так, пробовал разные варианты.
← →
Viewer (2002-07-12 22:12) [9]Могу сказать, что для простых СУБД делал так:
Загоняется таблица в наследник TTreeView
Далее от выбранного узла рекурсией составляется список id нужных записей, затем SELECT... IN (..) эти записи выбираются.
Если это на форие делается, то как бы само собой и получается.
TV уже есть и прорисован.
← →
Griffin (2002-07-14 21:40) [10]--- для Viewer
>Могу сказать, что для простых СУБД делал так:
>Загоняется таблица в наследник TTreeView...
Это, конечно, все хорошо, но весь вопрос в том, чтобы именно эти растакие номера всех потомков и получить для произвольного родителя. Ищем номера потомков первого уровня, затем ПО КАЖДОМУ ищем потомков второго и т.д. И всякий раз делаем запрос. Это наипростейшее решение вопроса, но по причине простоты оно и тормозит. Была у меня еще идея, чтобы во время работы СУБД хранила дерево всех людей и отслеживала изменения в их номерах, но уж оказалось чересчур муторно будет искать ошибки, ежели чего.
Да и лишний внешний файл данных неохота оставлять на поругание юзверям. Поэтому я и пошел искать совета в форум.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.08.05;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.005 c