Сконструировать запрос "по дереву" - получить "коэффициент"

SQL во всех проявлениях - от ANSI-92 до TSQL.

Модераторы: Yurich, Absurd

Ответить
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

31 авг 2010, 10:22

Здравствуйте, коллеги.

По работе родилась небольшая подзадачка.

Имеется простенькая таблица, реализующая древовидные данные:

Код: Выделить всё

Create Table Relations (
  Master_id  Integer        not null,
  Detail_id  Integer        not null,
  Master_Detail_rate number not null
)
Т.е. вся загвоздка (забегая вперед) в наличии поля коэффициента Master_Detail_rate.

Задача. Имея некий исходный ID (pStart_ID), требуется получить "линейный" список всех "узлов поддерева с вершиной в pStart_ID" с коэффициентом, равным произведению всех Master_Detail_rate, для всей цепочки связей, "протянувшихся" от "вершины" pStart_ID до данного (текущего) узла.

Если бы не было этого коэффициента (и не нужно было бы его получать), то список получался бы легко через connect by prior:

Код: Выделить всё

select pStart_ID as ID  from dual
  union all
select
    R.Detail_ID as ID
  from
    Relations R
  CONNECT BY PRIOR R.Detail_ID = R.Master_ID
    start with
      (R.Master_ID = pStart_ID)
Но как получить вторым полем "суммарный" коэффициет, придумать не получается. Т.е., результат хотелось бы получить такой:

Код: Выделить всё

select pStart_ID as ID, 1 as TOTAL_RATE from dual
  union all
select
    R.Detail_ID as ID,
    -- вместо  ????????????? хочется получить
    -- произведение полей R.Master_Detail_rate
    -- для всей цепочки связей, "протянувшихся"
    -- начиная от ROOT до текущего "узла"
    ????????????? as TOTAL_RATE
  from
    Relations R
    CONNECT BY PRIOR R.Detail_ID = R.Master_ID
    start with
      (R.Master_ID = pStart_ID)
Буду благодарен, если кто-то сумеет подсказать какое-нибудь изящное "magic decision" :)
ssDev
Сообщения: 50
Зарегистрирован: 20 янв 2005, 14:41

22 сен 2010, 10:59

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

Код: Выделить всё

select a.id,a.rate,exp(sum(LN(b.rate)))
from 
(select R.Detail_ID  ID,MASTER_DETAIL_RATE rate,level lv
  from Relations R
  CONNECT BY prior R.Detail_ID = R.Master_ID
    start with (R.Master_ID = pStart_ID)
 ) a,
 (select R.Detail_ID  ID,MASTER_DETAIL_RATE rate,level lv
  from Relations R
  CONNECT BY prior R.Detail_ID = R.Master_ID
    start with (R.Master_ID = pStart_ID)
 ) b
where b.lv>a.lv
group by a.id,a.rate
[code]
Ответить