powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Прочитать часть дерева из таблицы
21 сообщений из 21, страница 1 из 1
Прочитать часть дерева из таблицы
    #39617194
vochupin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

Есть две таблицы:

1) в которой хранится дерево:

create table tree_table(
node_id number,
parent_id number
);

2) и таблица в которой хранятся текстовые параметры для некоторых узлов дерева:

create table tree_node_parameter(
node_id number,
parameter varchar2
);

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

Узел может быть где-то посередине ветки, но ветки содержащие такой узел надо вычитать полностью.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617202
Фотография шК0ДЕР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vochupin,
Код: 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.
35.
with tree_table as 
 (select 1 as node_id, null as parent_id from dual
    union all 
  select 2, null from dual
    union all 
  select 3, 1 from dual
    union all 
  select 4, 1 from dual
    union all 
  select 5, 2 from dual
    union all 
  select 6, 2 from dual
    union all 
  select 7, 3 from dual
    union all 
  select 8, 3 from dual
    union all 
  select 9, 5 from dual
    union all 
  select 10, 5 from dual),
tree_node_parameter as 
 (select 4 as node_id, 'value 1' as parameter from dual
    union all
  select 6 as node_id, 'value 2' from dual
    union all
  select 10 as node_id, 'value 3' from dual)
select t.node_id,
       t.parent_id,
       p.parameter,
       level
  from tree_table t
  left join tree_node_parameter p
    on p.node_id = t.node_id
connect by prior t.parent_id = t.node_id
 start with p.parameter = 'value 3'
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617222
XMLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
шК0ДЕР,
Зачем ветку пилишь? Пользователь просил вычитывать полностью.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617234
vochupin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
шК0ДЕР,

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

Сильно кривым бы выглядел union двух селектов:

1) от узла с параметром до корня
2) от узла с параметром к листам

?

Мне просто надо полностью ветки до листов.

PS: простите тупого жависта :)
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617249
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
with tree_table as
(select 1 as node_id, null as parent_id from dual
union all
select 2, null from dual
union all
select 3, 1 from dual
union all
select 4, 1 from dual
union all
select 5, 2 from dual
union all
select 6, 2 from dual
union all
select 7, 3 from dual
union all
select 8, 3 from dual
union all
select 9, 5 from dual
union all
select 10, 5 from dual),
tree_node_parameter as
(select 4 as node_id, 'value 1' as parameter from dual
union all
select 6 as node_id, 'value 2' from dual
union all
select 5 as node_id, 'value 3' from dual
union all
select 10 as node_id, 'value 4' from dual)
select t.node_id,
t.parent_id,
p.parameter,
level
from tree_table t
left join tree_node_parameter p
on p.node_id = t.node_id
connect by prior t.parent_id = t.node_id
start with p.parameter is not null
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617275
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vochupin,

веткі з ЗП = 3000
Код: 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.
SQL> ed
Wrote file afiedt.buf

  1  with t as (
  2   select
  3     empno
  4    ,level,lpad(' ',(level-1)*2)||ename ename
  5    ,sal
  6    ,SYS_CONNECT_BY_PATH(sal, ',') p1
  7   from emp e
  8   start with mgr is null
  9   connect by prior empno=mgr
 10  )
 11  select * from t where
 12    instr(','||p1||',',','||3000||',')<>0 or
 13    exists
 14     (select 1 from emp e2
 15      where sal=3000
 16      start with e2.empno=t.empno
 17*     connect by prior e2.empno=e2.mgr)
 18  /

     EMPNO      LEVEL ENAME                  SAL P1
---------- ---------- --------------- ---------- --------------------
      7839          1 KING                  5000 ,5000
      7566          2   JONES               2975 ,5000,2975
      7788          3     SCOTT             3000 ,5000,2975,3000
      7876          4       ADAMS           1100 ,5000,2975,3000,1100
      7902          3     FORD              3000 ,5000,2975,3000
      7369          4       SMITH            800 ,5000,2975,3000,800

6 rows selected.



....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617335
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
with recu(l, node_id, parent_id) as (
   select 0 l, node_id, parent_id from таблица where node_id in (условие)
   union all
   select t0.l + case when t0.node_id = t1.parent_id then 1 else -1 end, t1.node_id, t1.parent_id 
   from таблица t1
   join recu t0 on t0.l >= 0 and t0.node_id = t1.parent_id or t0.l <= 0 and t0.parent_id = t1.node_id
)

Если "условие" может отобрать несколько узлов одной ветви, записи задублируются с разным L.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617360
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SQL> ed
Wrote file afiedt.buf

  1  with tbl as (
  2  select ename node_id, mgr parent_id , sal from emp)
  3  , recu(l, node_id, parent_id) as (
  4     select cast(0 as number) l, node_id, parent_id from tbl where sal=3000
  5     union all
  6     select t0.l + case when t0.node_id = t1.parent_id then 1 else -1 end, t1.node_id, t1.parent_id
  7     from tbl t1
  8     join recu t0 on t0.l >= 0 and t0.node_id = t1.parent_id or t0.l <= 0 and t0.parent_id = t1.node_id
  9  )
 10* select * from recu
SQL> /
ERROR:
ORA-01722: invalid number



no rows selected



заслепило,
чет не могу найти из-за чего ORA-01722: invalid number


.....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617451
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

ето ж надо так очетятаться
Код: 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.
  1  with tbl as (
  2    select empno node_id, mgr parent_id , sal, ename from emp)
  3   , recu(l, node_id, parent_id,ename) as (
  4       select cast(0 as number) l, node_id, parent_id ,ename from tbl where sal=3000
  5       union all
  6       select t0.l + case when t0.node_id = t1.parent_id then 1 else -1 end, t1.node_id, t1.parent_id,t1.ename||' '||t0.ename
  7       from tbl t1
  8       join recu t0 on t0.l >= 0 and t0.node_id = t1.parent_id or t0.l <= 0 and t0.parent_id = t1.node_id
  9    )
 10* select * from recu
SQL> /

         L    NODE_ID  PARENT_ID ENAME
---------- ---------- ---------- --------------------
         0       7788       7566 SCOTT
         0       7902       7566 FORD
        -1       7566       7839 JONES SCOTT
         1       7876       7788 ADAMS SCOTT
         1       7369       7902 SMITH FORD
        -1       7566       7839 JONES FORD
        -2       7839            KING JONES SCOTT
        -2       7839            KING JONES FORD

8 rows selected.



немножко странно выглядит иерархия

.....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617563
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Staxстранно выглядит иерархияне иерархия, сортировка
Код: plsql
1.
2.
3.
) search depth first by l, node_id set x
...
order by sign(l) * x
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617594
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-Staxстранно выглядит иерархияне иерархия, сортировка
Код: plsql
1.
2.
3.
) search depth first by l, node_id set x
...
order by sign(l) * x



мало помогает, надо допиливать

Код: 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.
  1  with tbl as (
  2    select empno node_id, mgr parent_id , sal, ename from emp)
  3   , recu(l, node_id, parent_id,ename) as (
  4       select cast(0 as number) l, node_id, parent_id ,ename from tbl where sal=3000
  5       union all
  6       select t0.l + case when t0.node_id = t1.parent_id then 1 else -1 end, t1.node_id, t1.parent_id,t1.ename||' '||t0.enam
  7       from tbl t1
  8       join recu t0 on t0.l >= 0 and t0.node_id = t1.parent_id or t0.l <= 0 and t0.parent_id = t1.node_id
  9    )
 10  search depth first by l, node_id set x
 11  select * from recu
 12* order by sign(l) * x
SQL> /

         L    NODE_ID  PARENT_ID ENAME                         X
---------- ---------- ---------- -------------------- ----------
        -2       7839            KING JONES FORD               7
        -1       7566       7839 JONES FORD                    6
        -2       7839            KING JONES SCOTT              3
        -1       7566       7839 JONES SCOTT                   2
         0       7788       7566 SCOTT                         1
         0       7902       7566 FORD                          5
         1       7876       7788 ADAMS SCOTT                   4
         1       7369       7902 SMITH FORD                    8

8 rows selected.


....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617663
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Staxмало помогает, надо допиливать


А теперь возьми общий случай когда у child > 1 parent. Тогда не то что допиливать - перекраивать надо.

SY.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617699
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYStaxмало помогает, надо допиливать


А теперь возьми общий случай когда у child > 1 parent. Тогда не то что допиливать - перекраивать надо.

SY.

у одного дитя два родителя?

должно работать 21270432

....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617726
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

В emp у empno только один mgr.

SY.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617743
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYStax,

В emp у empno только один mgr.

SY.

понятно что в емп нет (мне ж лень было набивать тестовую иерархию)

Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
SQL> /

     EMPNO      LEVEL ENAME                       SAL P1
---------- ---------- -------------------- ---------- --------------------
         1          1 a                           100 ,100
         2          2   b                        3000 ,100,3000
         3          3     c                       200 ,100,3000,200
         5          4       e                     300 ,100,3000,200,300
         4          2   d                        3001 ,100,3001
         3          3     b                      3000 ,100,3001,3000
         5          4       e                     300 ,100,3001,3000,300
         6          2   f                         302 ,100,302
         7          3     g                       303 ,100,302,303
         8          3     e                       304 ,100,302,304


  1  with tbl as (
  2    select 1 empno, 0 mgr , 100 sal, 'a' ename from dual union all
  3    select 2 node_id, 1 parent_id , 3000 sal, 'b' ename from dual union all
  4    select 3 node_id, 2 parent_id , 200 sal, 'c' ename from dual union all
  5    select 4 node_id, 1 parent_id , 3001 sal, 'd' ename from dual union all
  6    select 3 node_id, 4 parent_id , 3000 sal, 'b' ename from dual union all
  7    select 5 node_id, 3 parent_id , 300 sal, 'e' ename from dual union all
  8    select 6 node_id, 1 parent_id , 302 sal, 'f' ename from dual union all
  9    select 7 node_id, 6 parent_id , 303 sal, 'g' ename from dual union all
 10    select 8 node_id, 6 parent_id , 304 sal, 'e' ename from dual
 11  )
 12  ,t as (
 13     select
 14       empno
 15      ,level,lpad(' ',(level-1)*2)||ename ename
 16      ,sal
 17      ,SYS_CONNECT_BY_PATH(sal, ',') p1
 18     from tbl e
 19     start with mgr=0
 20     connect by prior empno=mgr
 21    )
 22    select * from t
 23    where
 24      instr(','||p1||',',','||3000||',')<>0 or
 25      exists
 26       (select 1 from tbl e2
 27        where sal=3000
 28        start with e2.empno=t.empno
 29*       connect by prior e2.empno=e2.mgr)
SQL> /

     EMPNO      LEVEL ENAME                       SAL P1
---------- ---------- -------------------- ---------- --------------------
         1          1 a                           100 ,100
         2          2   b                        3000 ,100,3000
         3          3     c                       200 ,100,3000,200
         5          4       e                     300 ,100,3000,200,300
         4          2   d                        3001 ,100,3001
         3          3     b                      3000 ,100,3001,3000
         5          4       e                     300 ,100,3001,3000,300

7 rows selected.
SQL>




.....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617751
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Ну и у какого empno в твоем примере два (или более) mgr? Еще раз - общий случай это когда и у начальника много подчиненных (это таблица emp и твой последний пример) и у подчиненного много начальников.

SY.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617752
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYStax,

Ну и у какого empno в твоем примере два (или более) mgr? Еще раз - общий случай это когда и у начальника много подчиненных (это таблица emp и твой последний пример) и у подчиненного много начальников.

SY.

у b (ид 2) два начальника a и d

зы
не понимаю какие нужны тестовые данные

.....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617755
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс - не заметил empno = 3.

SY.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617756
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

понял надо одинаковые ид для b
Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
     EMPNO      LEVEL ENAME                       SAL P1
---------- ---------- -------------------- ---------- --------------------
         1          1 a                           100 ,100
         2          2   b                        3000 ,100,3000
         3          3     c                       200 ,100,3000,200
         5          3     e                       300 ,100,3000,300
         4          2   d                        3001 ,100,3001
         2          3     b                      3000 ,100,3001,3000
         3          4       c                     200 ,100,3001,3000,200
         5          4       e                     300 ,100,3001,3000,300
         6          2   f                         302 ,100,302
         7          3     g                       303 ,100,302,303
         8          3     e                       304 ,100,302,304


  1  with tbl as (
  2    select 1 empno, 0 mgr , 100 sal, 'a' ename from dual union all
  3    select 2 node_id, 1 parent_id , 3000 sal, 'b' ename from dual union all
  4    select 3 node_id, 2 parent_id , 200 sal, 'c' ename from dual union all
  5    select 4 node_id, 1 parent_id , 3001 sal, 'd' ename from dual union all
  6    select 2 node_id, 4 parent_id , 3000 sal, 'b' ename from dual union all
  7    select 5 node_id, 2 parent_id , 300 sal, 'e' ename from dual union all
  8    select 6 node_id, 1 parent_id , 302 sal, 'f' ename from dual union all
  9    select 7 node_id, 6 parent_id , 303 sal, 'g' ename from dual union all
 10    select 8 node_id, 6 parent_id , 304 sal, 'e' ename from dual
 11  )
 12  ,t as (
 13     select
 14       empno
 15      ,level,lpad(' ',(level-1)*2)||ename ename
 16      ,sal
 17      ,SYS_CONNECT_BY_PATH(sal, ',') p1
 18     from tbl e
 19     start with mgr=0
 20     connect by prior empno=mgr
 21    )
 22    select * from t
 23    where
 24      instr(','||p1||',',','||3000||',')<>0 or
 25      exists
 26       (select 1 from tbl e2
 27        where sal=3000
 28        start with e2.empno=t.empno
 29*       connect by prior e2.empno=e2.mgr)
SQL> /

     EMPNO      LEVEL ENAME                       SAL P1
---------- ---------- -------------------- ---------- --------------------
         1          1 a                           100 ,100
         2          2   b                        3000 ,100,3000
         3          3     c                       200 ,100,3000,200
         5          3     e                       300 ,100,3000,300
         4          2   d                        3001 ,100,3001
         2          3     b                      3000 ,100,3001,3000
         3          4       c                     200 ,100,3001,3000,200
         5          4       e                     300 ,100,3001,3000,300

8 rows selected.




....
stax
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617759
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Ну это построение всей иерархии а затем выборка нужных строк что не есть оптимально/эффективно. Я имел ввиду выборку только нужных строк в случае когда у parent/child много child/parent.

SY.
...
Рейтинг: 0 / 0
Прочитать часть дерева из таблицы
    #39617762
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYStax,

Ну это построение всей иерархии а затем выборка нужных строк что не есть оптимально/эффективно. Я имел ввиду выборку только нужных строк в случае когда у parent/child много child/parent.

SY.
понятно что не оптімально, но другого я пока не придумал

ps
второй коннект бай можна наверное ограничить до узла из условия

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


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