Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Порядковый номер элемента дерева. / 20 сообщений из 20, страница 1 из 1
26.06.2018, 12:33
    #39665923
c-net
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
Добрый день!

Есть таблица для построения дерева
id (порядковый номер), id_parent, Short_Number(порядковый номер внутри родителя), unit_name, long_number


как мне собрать для каждой строки таблицы порядковый номер вида 1.2.1...., в поле long_number , где последняя цифра это Short_Number ?


дерево строится вот так:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
DECLARE
  q varchar2(4000);
begin 


здесь надо пробежать по таблице и перед построением дерева собрать long_number

  q:='   select case when connect_by_isleaf = 1 then 0 ';
  q:=q||'       when level = 1             then 1 ';
  q:=q||'       else                           -1 ';
  q:=q||'       end as status,  ';  
  q:=q||'  level, ';
  q:=q||'       long_number || '' '' || unit_name	 as title,';
  q:=q||'    ''icon-gear'' as  icon, ';
 q:=q||'   ID_REESTR as value, ';
 q:=q||'   null as tooltip, ';
 q:=q||'  ''javascript:pageItemValue(''||apex_escape.js_literal(ID_REESTR)||''); pageItemValue2(''||apex_escape.js_literal(unit_name)||'');'' as link ';
 q:=q||'   from REESTR';
 q:=q||'   connect by prior ID_REESTR = ID_PARENT  ';

 
 
  if :f_vid != 'ALL'   then
    q:=q||'start with vid= :f_vid ';

  else
  q:=q||'  start with ID_REESTR=1  ';
  end if;

  return q;
end;



то есть в
Код: plsql
1.
long_number || '' '' || unit_name	 as title,';



нужно получить

1. Имя1
1.1 Имя2
1.2 Имя3
2. Имя4
2.1 Имя5
2.1.1 Имя6
...


может и не перед построением дерева, а отдельным тригером, но это неважно. не могу сообразить как номер собрать оптимально, без извращений.
...
Рейтинг: 0 / 0
26.06.2018, 12:43
    #39665934
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-net,

строить иерархию с помощью with

.....
stax
...
Рейтинг: 0 / 0
26.06.2018, 12:45
    #39665937
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
Код: plsql
1.
row_number() over (partition by id_parent order by unit_name) rn
...
Рейтинг: 0 / 0
26.06.2018, 12:50
    #39665950
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-net,

нашел Рекурсивный запрос.

....
stax
...
Рейтинг: 0 / 0
26.06.2018, 13:00
    #39665959
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
column name       format a10
column level_name format a13
column pth        format a10

set lines 150

with s (id, parent_id, name) as 
(select 1  id, null parent_id, 'root'   from dual union all
 select 10 id, 1    parent_id, 'name 1' from dual union all
 select 20 id, 1    parent_id, 'name 2' from dual union all
 select 30 id, 10   parent_id, 'name 3' from dual union all
 select 40 id, 10   parent_id, 'name 4' from dual union all
 select 50 id, 20   parent_id, 'name 5' from dual union all
 select 60 id, 20   parent_id, 'name 6' from dual
)
select id, parent_id, name, lpad(' ', (level - 1) * 2) || name level_name, ltrim(sys_connect_by_path(rn, '.'), '.') pth, connect_by_isleaf is_leaf
from 
  (select s.*, row_number() over (partition by parent_id order by name) rn
   from s
  ) s
start with parent_id is null
connect by prior id = parent_id;

        ID  PARENT_ID NAME       LEVEL_NAME    PTH           IS_LEAF
---------- ---------- ---------- ------------- ---------- ----------
         1            root       root          1                   0
        10          1 name 1       name 1      1.1                 0
        30         10 name 3         name 3    1.1.1               1
        40         10 name 4         name 4    1.1.2               1
        20          1 name 2       name 2      1.2                 0
        50         20 name 5         name 5    1.2.1               1
        60         20 name 6         name 6    1.2.2               1

7 rows selected.
...
Рейтинг: 0 / 0
26.06.2018, 13:30
    #39665980
c-net
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
AmKad, класс!! похоже оно, сейчас буду прикручивать себе, спасибо!
...
Рейтинг: 0 / 0
26.06.2018, 15:18
    #39666072
c-net
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-net,

Прикрутил к себе!
Благодаря предложенному варианту, не надо формировать новый столбец long_number, номер формируется на лету.
Классное решение, спасибо!


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
select case when connect_by_isleaf = 1 then 0
            when level = 1             then 1
            else                           -1
       end as status, 
       level, 
       
       ltrim(sys_connect_by_path(rn, '.'), '.') || ' ' || unit_name	 as title, 
       'icon-gear' as icon, 
       ID_REESTR as value, 
       null as tooltip, 
       null as link 
      
       
from (select reestr.*, row_number() over (partition by id_parent order by short_number) rn  
   from reestr 
  )  
start with ID_REESTR=1
connect by prior ID_REESTR = ID_PARENT 




Но есть ньюанс, как мне убрать номер с первых двух уровней? were при start with запихивать нельзя. Ну это мелочи. буду думать, спасибо еще раз.
...
Рейтинг: 0 / 0
26.06.2018, 15:32
    #39666082
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-netНо есть ньюанс, как мне убрать номер с первых двух уровней? were при start with запихивать нельзя. Ну это мелочи. буду думать, спасибо еще раз.

оставить (substr) после второй точки, не оно?

.....
stax
...
Рейтинг: 0 / 0
26.06.2018, 15:39
    #39666085
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
Staxоставить (substr) после второй точки, не оно?По его формулировке может быть три варианта: оно, не оно и третий вариант.
...
Рейтинг: 0 / 0
26.06.2018, 15:57
    #39666097
c-net
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
Stax,
немного не оно.

сейчас идет

1 Название1
1.1 Название2
1.1.1 Название3
...

без нарушения иерархии у названия1 и Название2 не должно быть номера. Должно выглядеть так:

Название1
Название2
1 Название3

Отрезать substr надо как-то и 1, и 1.1 и 1.1.
Читаю, но это наверное костыль...
...
Рейтинг: 0 / 0
26.06.2018, 16:05
    #39666103
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-netДолжно выглядеть так:

Название1
Название2
1 Название3

Отрезать substr надо как-то и 1, и 1.1 и 1.1.
Читаю, но это наверное костыль...Достаточно писать номер только для level>2.
...
Рейтинг: 0 / 0
26.06.2018, 16:19
    #39666113
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
Код: plsql
1.
ltrim(sys_connect_by_path(case when level > 2 then rn end, '.'), '.') pth
...
Рейтинг: 0 / 0
26.06.2018, 16:25
    #39666115
c-net
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
AmKad, -2- ,

ААА!! ОГОНЬ!

Спасибо за разжевывание! все отлично сработало!
...
Рейтинг: 0 / 0
27.06.2018, 10:15
    #39666358
c-net
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
не сочтите за наглость...
А если все же записать полученные данные, что не так делаю (ругается: SQL command not properly ended)?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
UPDATE reestr
SET long_number= (
select ltrim(sys_connect_by_path(case when level > 2 then rn end, '.'), '.') 
FROM
  (select reestr.*, row_number() over (partition by id_parent order by short_number) rn
   from reestr)   
start with id_reestr =1
connect by prior id_reestr = id_parent) AA
WHERE reestr.id_reestr= AA.id_reestr ;



сам Select работает четко.
...
Рейтинг: 0 / 0
27.06.2018, 10:24
    #39666363
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
where до connect
...
Рейтинг: 0 / 0
27.06.2018, 10:26
    #39666365
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
нет, с connect все верно
...
Рейтинг: 0 / 0
27.06.2018, 10:27
    #39666369
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-net,

Тебе нужен merge. В твоем же случае если благодаря предикату не вернется ни одной строки, запрос обновит поле в null - держу пари это не ожидаемое тобой поведение.
...
Рейтинг: 0 / 0
27.06.2018, 10:45
    #39666384
MaximaXXL
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-net,

А Вас не смущает что Вы ежа с ужем крестите?
Код: plsql
1.
WHERE reestr.id_reestr= AA.id_reestr ;


Что такое AA в разрезе update ?
...
Рейтинг: 0 / 0
27.06.2018, 16:07
    #39666676
c-net
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
AmKad, получилось! Аж самому не верится

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
MERGE into reestr t1
      using (select id_reestr, ltrim(sys_connect_by_path(case when level > 2 then rn end, '.'), '.') pth
FROM
  (select reestr.*, row_number() over (partition by id_parent order by short_number) rn
   from reestr)   
start with id_reestr =1
connect by prior id_reestr = id_parent) t2
      on (t1.id_reestr = t2.id_reestr )
      when matched then 
        update 
         set t1.long_number = t2.pth;
...
Рейтинг: 0 / 0
27.06.2018, 16:26
    #39666690
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядковый номер элемента дерева.
c-netAmKad, получилось! Аж самому не верится


в update не верете?
Вы скобками ошиблісь
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
  1  UPDATE reestr
  2  SET long_number= (select l from (
  3  select ltrim(sys_connect_by_path(case when level > 0.2 then rn end, '.'), '.') l,id_reestr
  4  FROM
  5    (select reestr.*, row_number() over (partition by id_parent order by short_number) rn
  6     from reestr)
  7  start with id_reestr =1
  8  connect by prior id_reestr = id_parent
  9  ) AA
 10* WHERE reestr.id_reestr= AA.id_reestr )
SQL> /

7 rows updated.

SQL> select * from reestr;

 ID_REESTR  ID_PARENT SHORT_NUMB LONG_NUMBER
---------- ---------- ---------- --------------------
         1            root       1
        10          1 name 1     1.1
        20          1 name 2     1.2
        30         10 name 3     1.1.1
        40         10 name 4     1.1.2
        50         20 name 5     1.2.1
        60         20 name 6     1.2.2

7 rows selected.




ps
я так понимаю, у детяти один родитель
.....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Порядковый номер элемента дерева. / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]