Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2009.04.19;
Скачать: [xml.tar.bz2];

Вниз

По умолчанию Рекурсивный запрос к БД - не могу сообразить как   Найти похожие ветки 

 
frippy   (2008-08-21 21:50) [0]

есть список людей, с именами, адресами и т.д.
У каждой записи есть свой ID - генерится сервером (Interbase)
У некоторых людей в списке есть "подчинённые" - они получают свой ID, но ещё и номер "главного".
В итоге таблица получается "деревом" - у каждого подчинённого могут ещё быть люди в подчинении.
Когда выбираем "самого главного" - видим весь список людей.
Когда выбираем одного из подчинённых - видим список его подчинённых И подчинённых этого подчинённого.
Что не понимаю как сделать - вывести всех подчинённых выбранного подчинённого "вглубь"
Может я немонго сумбурно объяснил, наверное, но суть такова - выбрав на 1-м уровне я должен видеть все уровни вглубь (не важно сколько их),
выбрав 2-й уровень я должен увидеть всех на 3-м, 4-м и т.д. уровнях.
Посмотреть подчинённых без "рекурсии вглубь" - делается на ура и легко, а вот как дальше - не пойму.
Пишется всё на Delphi2006 + IB7


 
stas ©   (2008-08-21 22:01) [1]

Нужно объединить таблицу саму с собой столько раз сколько вложенностей, либо рекурсия либо цикл.
На работе пример есть на MSSQL, завтра скину.
Смысл такой объединяешь таблицу саму с сабой результат списываешь во временную таблицу, а потом в цикле объединяешь временную таблицу саму с собой и списываешь в нее же результат,  пока результат небудет NULL.


 
Евгений Р.   (2008-08-21 22:04) [2]

for
  select idf
  from tbl
  where idfGlavn=:idf into :idfOut do Begin
  suspend;
  for select idf
       from ЭтаПроцедура(:idfOut) into :idfOut do suspend;
End;


 
stas ©   (2008-08-21 22:04) [3]

тут посмотри:
http://delphimaster.net/view/3-1213899571/


 
frippy   (2008-08-21 22:06) [4]

Объединять саму с собой таблицу это хорошо, но...у меня 10 машин будут одновременно делать это. Думаю варинат не приемлем :(

А вот рекурсия-цикл - да, но не могу сообразить как
Для одного человека я сделал так:

var
 number: integer;
begin
 if DBGrid4.SelectedField.AsString<>"" then
//если есть человек, чьих подчинённых ищем
   begin
     IBQuery3.SQL.Clear;
     IBQuery3.SQL.Add("select * from list where num="+DBGrid4.SelectedField.AsString);
//нашли человека, узнаём кто его "главный"
     IBQuery3.Open;
     number:=DBGrid4.SelectedField.AsInteger;
     IBQuery3.Locate("num",number,[]);
     IBQuery1.SQL.Clear;
     IBQuery1.SQL.Add("select * from list where main="""+Inttostr (number)+"""");
//нашли всех, у кого главным записан человек с ID=number
     IBQuery1.Open;
 end;

это работает на любую "глубину" но только для одного человека и только его подчинённых.


 
frippy   (2008-08-21 22:14) [5]

2stas - временная таблица не годится, у меня 10 человек будет добавлять записи и делать выборки одновременно

Евгений Р. - а можно поподробней, если не затруднит...?


 
Евгений Р.   (2008-08-21 22:40) [6]

tbl - таблица с людьми
idf - идф. человека
idfGlavn-идф.начальника

Хранимая процедура
вх.параметр - Idf
выходной - IdfOut

результат - список idf всех подчиненных

внешний цикл - выбираем и выдаем всех подчиненных предыдущего уровня
внутренний цикл - рекурсивно выдаем для каждого подчиненного всех подчиненных


 
frippy   (2008-08-21 22:44) [7]

идущий да обрящет....

думаю что удалось побороть, вот статья:
http://www.az-design.ru/Support/DataBase/Heiven13.shtml

конкретно - делаем процедуру и запрос

осталось проверить в деле......


 
Prohodil Mimo ©   (2008-08-21 23:23) [8]

ещё на ibase.ru есть статьи.
Но я предпочитаю на клиенте дерево генерить.


 
stas ©   (2008-08-22 08:56) [9]

frippy   (21.08.08 22:06) [4]
Да хоть 100. Вы же придумали такую структуру - не я.
Тяжеловато конечно будет работать рекурсия. Я выше ссылку давал там я описывал как триггерами наполнять постоянную таблицу в момент заполнения вашей таблицы.


 
место   (2008-08-22 13:42) [10]

нет возможности проверить, но по идее так можно получить полный список

select a.id_people, a.people_name, b.id_people, b.people_name
from t_people a, t_people b
where a.id_people = b.id_owner
order by a.id_people, b.id_people


 
stas ©   (2008-08-22 15:11) [11]

место   (22.08.08 13:42) [10]
Нет это только 2-й уровень


 
Труп Васи Доброго ©   (2008-08-22 16:44) [12]

вот тебе процедура готовая и работающая

SET TERM ^ ;

CREATE OR ALTER PROCEDURE ADRESS_SEL_DOWN (
   id1 INTEGER)
RETURNS (
   id INTEGER)
AS
begin
 for SELECT id FROM s_adres where s_adres.pid=:id1 into :id DO
   begin
     suspend;
     IF (EXISTS(SELECT id FROM s_adres where s_adres.pid =:id)) THEN
       BEGIN
         FOR SELECT id from ADRESS_SEL_DOWN(:id) INTO :id DO
           SUSPEND;
       END
   end

end^

SET TERM ; ^

таблица s_adres в ней ID это ID, а PID это Parent ID короче всё как у тебя.


 
Vlad Oshin ©   (2008-08-22 17:14) [13]

http://yandex.ru/yandsearch?&text=%D1%81%D0%B2%D0%BE%D0%B8%D0%BC%D0%B8%20%D1%80%D1%83%D0%BA%D0%B0%D0%BC%D0%B8%20%D0%A4%D0%B8%D0%BB%D0%B8%D0%BF%D0%BF%D0%BE%D0%B2%D0%B0%20delphi&msp=1



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2009.04.19;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.052 c
1-1211299976
nicestep
2008-05-20 20:12
2009.04.19
Параллельный порт. Асинхронная запись/чтение


15-1228829198
wink
2008-12-09 16:26
2009.04.19
Delphi и GPIB?


15-1234985702
Unknown user
2009-02-18 22:35
2009.04.19
процесс отладки


15-1235073067
DmitryG.
2009-02-19 22:51
2009.04.19
UnZip TMemoryStream


15-1235208148
Индеец
2009-02-21 12:22
2009.04.19
Компоненты для сжатия данных





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский