Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Иерархия, выбрать ветку и первого родителя.  [new]
BRita
Member

Откуда:
Сообщений: 51
Здравствуйте.
Задача вроде не сложна, но как бы покрасивее сделать.
Нужно с некого элемента иерархии вывести его родителей и их первого предка, т.е. узел с которого данная ветка и началась.
Пока получилось что-то вроде следующего, но мне не нравиться, может у кого есть идеи получше.
 select T.RN, 
        T.EQPARENT,
        SYS_CONNECT_BY_PATH(T.RN, '\') RN_PATH,
        T_HRN.RN 
   from EQCONFIG T,
        (
           select IN_T.RN
             from EQCONFIG IN_T
            where IN_T.EQPARENT is null
            connect by IN_T.RN = prior IN_T.EQPARENT
             start with IN_T.RN = 23027314 
        ) T_HRN
connect by T.RN = prior T.EQPARENT
  start with T.RN = 23027314 
12 мар 07, 11:03    [3886073]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
Elic
Member

Откуда:
Сообщений: 29991
last_value(T.RN) over (order by level) as root_rn
12 мар 07, 11:18    [3886150]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
Бабичев Сергей
Member

Откуда:
Сообщений: 2498
2 автор

select T_HRN.*,
       last_value(T_HRN.RN) 
             over(order by lv rows between unbounded preceding and unbounded following ) rn_1
  from (
           select level as lv,
                  RN, 
                  EQPARENT,
                  SYS_CONNECT_BY_PATH(RN, '\') RN_PATH
             from EQCONFIG IN_T
            connect by IN_T.RN = prior IN_T.EQPARENT
             start with IN_T.RN = 23027314 
        ) T_HRN
12 мар 07, 11:39    [3886269]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
Elic
Member

Откуда:
Сообщений: 29991
Бабичев Сергей
select T_HRN.*,
last_value(T_HRN.RN)
over(order by lv rows between unbounded preceding and unbounded following ) rn_1
from (...) T_HRN
Точно, нужно inline view, из-за недружелюбности между аналитикой и SYS_CONNECT_BY_PATH.
А вот указание окна излишне.
12 мар 07, 11:54    [3886374]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
Бабичев Сергей
Member

Откуда:
Сообщений: 2498
Elic
А вот указание окна излишне.
IMHO, не твоя правда.
Вот небольшая зарисовочка.
Оригинальный запрос от автора:
with
  EQCONFIG as 
    (
      select 1 as rn, null as EQPARENT from dual union all
      select 2 as rn, 1 as EQPARENT from dual union all
      select 3 as rn, 2 as EQPARENT from dual
    )
--
select T.RN, 
        T.EQPARENT,
        SYS_CONNECT_BY_PATH(T.RN, '\') RN_PATH,
        T_HRN.RN 
   from EQCONFIG T,
        (
           select IN_T.RN
             from EQCONFIG IN_T
            where IN_T.EQPARENT is null
            connect by IN_T.RN = prior IN_T.EQPARENT
             start with IN_T.RN = 3 
        ) T_HRN
connect by T.RN = prior T.EQPARENT
  start with T.RN = 3 

Query finished, retrieving results...

RN   EQPARENT   RN_PATH   RN_1
--   --------   -------   ----
 3          2   \3           1
 2          1   \3\2         1
 1              \3\2\1       1

3 row(s) retrieved

Переработка:
with
  EQCONFIG as 
    (
      select 1 as rn, null as EQPARENT from dual union all
      select 2 as rn, 1 as EQPARENT from dual union all
      select 3 as rn, 2 as EQPARENT from dual
    )
--
select T_HRN.*,
       last_value(T_HRN.RN) 
             over(order by lv rows between unbounded preceding and unbounded following ) root_by_bsm,
       last_value(T_HRN.RN) 
             over(order by lv) root_by_elic
  from (
           select level as lv,
                  RN, 
                  EQPARENT,
                  SYS_CONNECT_BY_PATH(RN, '\') RN_PATH
             from EQCONFIG IN_T
            connect by IN_T.RN = prior IN_T.EQPARENT
             start with IN_T.RN = 3 
        ) T_HRN

Query finished, retrieving results...

RN   EQPARENT   RN_PATH   ROOT_BY_BSM   ROOT_BY_ELIC
--   --------   -------   -----------   ------------
 3          2   \3                  1              3 
 2          1   \3\2                1              2 
 1              \3\2\1              1              1 

3 row(s) retrieved
Если конструкцию окна не задавать, то корень строится не такой, как нужен автору...
12 мар 07, 12:17    [3886564]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
Elic
Member

Откуда:
Сообщений: 29991
Бабичев Сергей
Elic
А вот указание окна излишне.
не твоя правда.
Твоя правда. Посыпаю пеплом свою голову. Надо было написать:
min(rn) keep (dense_rank last order by lv) over () as root_rn
12 мар 07, 12:28    [3886634]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
Бабичев Сергей
Member

Откуда:
Сообщений: 2498
Elic
Надо было написать:
min(rn) keep (dense_rank last order by lv) over () as root_rn
Ну вот, это уже совсем другое дело ;)
12 мар 07, 12:40    [3886735]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
в 10g для сабж. есть оператор
select ename, connect_by_root ename as root_ename
      from scott.emp
      connect by prior empno = mgr
12 мар 07, 13:02    [3886873]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
Elic
Member

Откуда:
Сообщений: 29991
orawish
в 10g для сабж. есть оператор connect_by_root
Ты вопрос читал, но не понял :)
Тут небольшой парадоксик: когда корень является листом? - в обратной иерархии.
12 мар 07, 13:20    [3887002]     Ответить | Цитировать Сообщить модератору
 Re: Иерархия, выбрать ветку и первого родителя.  [new]
BRita
Member

Откуда:
Сообщений: 51
Огромное спасибо, точно нужна была аналитическая функция, ведь думала ещё. Спасибо. :)
12 мар 07, 13:50    [3887259]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить