Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft Access Новый топик    Ответить
 Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
тупой тopмoс
Guest
караул - полтора часа просидел заклинило - уже и не смешно даже

короче - таблица tblUnits с тремя полями нужно просчитать количество всех предков (нод направленного графа - я правильно выразился?)

UnitID - Num
UnitReportsTo - Num
UnitDescription - Txt

пишу в запросе вызов вида cntAncestor: q([UnitReportsTo])

пишу функцию паблик - рекурсия DlookUp'ом

' * что-то в этом роде - пишу навскидку, точно не помню - просто в общем мысль изложить
Public Fuction q(intParent as Integer) as Integer ' или Variant, чтобы на Null не обламываться
Do While Dcount("UnitID", "tblUnits", "[UnitID] = " & intParent)>0 ' до тех пор, пока не поднимемся до самого верха дерева
q (DlookUp("UnitID", "tblUnits", "[UnitReportsTo] = " & intParent)) ' ищем родителя отпрыска, и далее его родителя и далее и далее - поднимаемся по дереву
Exit Do
' по идее - считаем заходы по ходу и отдаем результат в запрос
Loop
End Function

пока погонял в холостую на примерку все нормально - надо счетчик ставить и возвращать q а тут атас - ступор как и куда а уже и на работу пора бежать - пока ковырял функцию кофе 10 раз остыл и на часах уже 8:30,

в спешке поменял алгоритм и c IF'ами ставил и с FOR...NEXT'ами - и вообще все в цикл уходит намертво - голова похмельная тяжелая не могу собраться и врубиться

помогите, а? я отбатрачу

ЗЫ

зря наверное я с агрегатными затеял?
6 окт 05, 10:49    [1943251]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
4321
Member [заблокирован]

Откуда:
Сообщений: 3573
см сродную задачу.
хучь тама тофи га лишнего, но зато тема бегли по иерархиям раскрыта
6 окт 05, 11:02    [1943333]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
тупой тopмoс
Guest
4321
тема бегли...


издеваешься? да? над больным человеком! дочитал до четвертой страницы - чуть не умер

у меня задача в 10 рас просче и записей в талбице меньше 1000 ИМХО можно гораздо проще обойтись - просто откровенно туплю.
6 окт 05, 11:13    [1943431]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
4321
Member [заблокирован]

Откуда:
Сообщений: 3573
тупой тopмoс
4321
тема бегли...


издеваешься?
ни разу
просто идеи:
0. рекурсивный вызов поиска пердка, в котром
1. индексированный поиск в одном рекордсете по переданному параметру
2. наваривание некой переменной кол-ва вызовов.

фсё.
6 окт 05, 11:40    [1943611]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
тупой тopмoс
Guest
4321
тупой тopмoс
4321
тема бегли...


издеваешься?
ни разу
просто идеи:
0. рекурсивный вызов поиска пердка, в котром
1. индексированный поиск в одном рекордсете по переданному параметру
2. наваривание некой переменной кол-ва вызовов.

фсё.


а у меня, по твоему, что напесано? тока не работает нифига

0. Do While (считаем пока будет где искать)
1. DlookUp (то, что ищем, там где ищем, по какому признаку)
2. то о чем и спрашиваю...

о-о-о кажицца наченаю падазревать - наверное ручками индексы пошуровал и двуголовое дерево получилось - когда потомок являецца предком родителя...

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

чао какао...
6 окт 05, 11:52    [1943700]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
Latuk
Member

Откуда: N 54°38', E 037°35'
Сообщений: 7310
Если наложить доп ограничение на кол-во предков
(если записей всего 1000 то вложенность наверно небольшая)
то можно решить задачу запросом с подзапросом с подзапросом ...

т.е. выбрать предков тех ктопредок тех кто предок и т.д.
кол-во подзапросов такое-же как мах глубина предков

если операция частая то стоит завести поле текстового ключа
куда записывать полное сетевое имя (ID-ники в порядке наследования через разделитель)
тогда такая задача решается одним запросом с Like по этому полю в Where
тока этот ключь придется пересчитывать при смене структуры предков

еще важно, может ли у нода быть несколько предков или это дерево.
6 окт 05, 12:07    [1943800]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
4321
Member [заблокирован]

Откуда:
Сообщений: 3573
Latuk
Если наложить доп ограничение на кол-во предков
достаточно заполнять массив/коллекцию id в процессе поиска и проверять вхождение вновь найденного id в массив/коллекцию (коллекция удобнее для поиска без сортировки - можно задавать key=Str(id) - ошибка вставки и будет повтором).
6 окт 05, 12:14    [1943843]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
тупой тopмoс
Guest
Latuk
Если наложить доп ограничение на кол-во предков
(если записей всего 1000 то вложенность наверно небольшая).


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

Latuk
если операция частая то стоит завести поле текстового ключа


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

Latuk
тока этот ключь придется пересчитывать при смене структуры предков


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

Latuk
еще важно, может ли у нода быть несколько предков или это дерево.


должно быть строгое дерево - я ляпнулся не обеспечив стройной иерархии - буду разобраться - посмотреть

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

рекурсия отрабатывает - пробегает от потомка к предку (прародитель для всех всегда один - самый верхний) пока не упрется в тот, у которого число всех предков равно 0 (Null)

объявляю счетчик в заголовке и плюсую его в функции - отрабатывает - т.е. в результате проходит все ветки всего дерева и плюсует все подряд - правда что именно плюсует не знаю результат не тестил и не соотносил

я ить почему спрашиваю -

не могу разобраться как воткнуть счетчик в саму функцию, получить его значение по окончании цикла и сбросить - закоротило меня :))
и немогу понять почему это может быть невозможно - если это может быть невозможно.

по большому буфету и вообще мне нужно оценить позицию нода в дереве разложив в запосе на 4 группы

прародитель всей ботвы - родителей 0
первая группа вложенности - прародителей 1
последняя группа вложенности - потомков 0
все остальные - более одного прародителя и не менее одного потомка
6 окт 05, 12:43    [1944038]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
тупой тopмoс
Guest
4321
достаточно заполнять массив/коллекцию id в процессе поиска


прочел читыре раза - нифига не понял (говорю-ж тормас)

зачем нам проверять каждый вновь найденый АйДи на присутствие его в коллекции - что это даст?

а размерность массива как определять будем?

хм... вообще-то - зная количество записей можно вычислить максимально возможное количество прародителей для всех потомков в сумме - ток верный ли это путь

или в Stack загонять по Гетцу? - смысл?

нужно просто посчитать количество вхождений в рекурсию ИМХО и отдать данные в запрос...
6 окт 05, 12:54    [1944123]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
4321
Member [заблокирован]

Откуда:
Сообщений: 3573
тупой тopмoс

не могу разобраться как воткнуть счетчик в саму функцию, получить его значение по окончании цикла и сбросить - закоротило меня :))
и немогу понять почему это может быть невозможно - если это может быть невозможно.

сбросить можно в самом начале (вызовом с параметром)

Private vCount As Long
Private rst as Recordset 'можно и как св-во

Public MyRecursiveFun(v_id As Long,Optional lCount As Long=0) As Long
Dim l_id as Long, next_pid AS Long
  'если не как св-во, то
  IF rst IS Nothing OR rst.Index<>... Then
      SET rst =...
      rst.Index = ...
  End IF
  vCount = lCount
   ...
   l_id = rst.Collect("pid")
   vCount = lCount + 1
   next_pid = MyRecursiveFun(l_id, vCount)
   MyRecursiveFun = l_id
...
   'конец рекурсии
   IF lCount = 0 then
       rst.close
       ....
   END IF
...

END Function
6 окт 05, 13:02    [1944175]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
4321
Member [заблокирован]

Откуда:
Сообщений: 3573
тупой тopмoс
зачем нам проверять каждый вновь найденый АйДи на присутствие его в коллекции - что это даст?

проверку колец

а размерность массива как определять будем?
ReDim знаите?

хм... вообще-то - зная количество записей можно вычислить максимально возможное количество прародителей для всех потомков в сумме - ток верный ли это путь
зачем гонять скажем 10000 раз рекурсию, если кольцо (саммоссылка ветки на своего потомка) найдется на 2-м круге?
6 окт 05, 13:05    [1944191]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
тупой тopмoс
Guest
4321
зачем гонять скажем


1 понял - колец не будет
2 да
3 в моем варианте ИМХО однопальцтвенно

as Sum - спасибо за поддержку и подсказки
6 окт 05, 13:24    [1944307]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
Latuk
Member

Откуда: N 54°38', E 037°35'
Сообщений: 7310
Вот налабал универсальное решение для графа
правда на T-SQL,но перевести я думаю не сложно

--Формирование таблицы пар предок->наследник при любой степени родства

--Начальная ссылка для того чтобы запросу было за что в начале зацепится
SELECT ChildID, ParentID INTO #Predok FROM Graph
--Из предков тех кто предок для, и уже вставлен в таблицу предков
--вставить в таблицу предков тех кто еще не вставлен
WHILE @@ROWCOUNT <>0--если запрос вернул хоть одну строку
INSERT INTO #Predok (ChildID, ParentID)
SELECT DISTINCT sqrd.ChildID, sqrd.ParentID
FROM (SELECT ParentGraph.ChildID, ChildGraph.ParentID
FROM Graph ParentGraph 
INNER JOIN #Predok ON ParentGraph.ChildID = #Predok.ChildID 
INNER JOIN Graph ChildGraph ON #Predok.ParentID = ChildGraph.ChildID) sqrd 
LEFT OUTER JOIN #Predok ON sqrd.ChildID = #Predok.ChildID AND sqrd.ParentID = #Predok.ParentID
WHERE (#Predok.ChildID IS NULL)

--Теперь можно вопросы
--например сколько у нода предков (-1 т.к. в таблице есть ссылка сам на сам)

SELECT ChildID,Count(ParentID)-1 AS КолВоПредков FROM #Predok GROUP BY ChildID

--или у конкретного нода
SELECT Count(ParentID)-1 AS КолВоПредков FROM #Predok WHERE ChildID=274

--Все предки
SELECT ParentID FROM #Predok WHERE ChildID=274
--Все дети
SELECT ChildID FROM #Predok WHERE ParentID=274

drop table #Predok

#Predok - может быть и не временной (особенно если иерархия меняется нечасто)

тогда ее надо будет пересчитывать при смене иерархии для нода
(или добавлении нового нода)
например если есть форма а в ней поле парент задающее иерархию
то на его событие после обновления повесить

--Удалить неактуальную инфу 
DELETE FROM Predok WHERE ChildID=НомерНода Or ParentID=НомерНода
--сформировать ее заново
INSERT INTO Predok (ChildID, ParentID)
SELECT ChildID, ParentID FROM Graph
--Из предков тех кто предок для, и уже вставлен в таблицу предков
--вставить в таблицу предков тех кто еще не вставлен
WHILE @@ROWCOUNT <>0--если запрос вернул хоть одну строку
INSERT INTO Predok (ChildID, ParentID)
SELECT DISTINCT sqrd.ChildID, sqrd.ParentID
FROM (SELECT ParentGraph.ChildID, ChildGraph.ParentID
FROM Graph ParentGraph 
INNER JOIN Predok ON ParentGraph.ChildID = Predok.ChildID 
INNER JOIN Graph ChildGraph ON Predok.ParentID = ChildGraph.ChildID) sqrd 
LEFT OUTER JOIN Predok ON sqrd.ChildID = Predok.ChildID AND sqrd.ParentID = Predok.ParentID
WHERE (Predok.ChildID IS NULL)
6 окт 05, 13:40    [1944414]     Ответить | Цитировать Сообщить модератору
 Re: Уважаемые... подсчитать количество предков записи в таблице Parent Child  [new]
Latuk
Member

Откуда: N 54°38', E 037°35'
Сообщений: 7310
здеся поправить для конкретного узла
--сформировать ее заново
INSERT INTO Predok (ChildID, ParentID)
VALUES(НомерНода,НомерНода)
6 окт 05, 13:44    [1944442]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft Access Ответить