Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.59 MB
Время: 0.023 c
6-13757
Xein
2002-05-21 01:05
2002.08.05
Насчёт Звонилки......


1-13670
Sectey
2002-07-23 15:30
2002.08.05
p


7-13834
Alexsandr
2002-05-21 18:41
2002.08.05
Работа с портом ВВ в NT


1-13714
madcap
2002-07-23 23:01
2002.08.05
Обработчик события


6-13740
lynx
2002-05-21 14:10
2002.08.05
Сетевое окружение





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский