Гость
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Connect by / 13 сообщений из 13, страница 1 из 1
13.12.2021, 08:40
    #40119552
zipperxz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Уважаемые форумчане, добрый день!

Подскажите, пжлста, с идеями решения задачи, у самого кончились.

Имеется таблица вида:
1 столбец - иерархический код через точку (1.2.3.3),
2 столбец - описание названия данного уровня (например, дверь шкафа, ручка и т.д.)

Требуется составить запрос, в котором будет выведен полный путь для каждого уровня (мебель>шкаф>дверца...).

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

Спасибо!
...
Рейтинг: 0 / 0
13.12.2021, 12:14
    #40119601
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
zipperxz

Имеется таблица вида:

приведите пример данных (желательно с помощью with)

Код: plsql
1.
2.
3.
4.
5.
6.
with t(p,n) as (
 select '1.2.3.3','Шуруп' from dual
 --union all
)
select * from t
/



.....
stax
...
Рейтинг: 0 / 0
13.12.2021, 14:05
    #40119638
zipperxz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Stax,

with t as(
select '1.2.1' as code, 'дверца' as name from dual
union all
select '1.2' as code, 'шкаф' as name from dual
union all
select '1' as code, 'мебель домашняя' as name from dual
union all
select '2' as code, 'бытовая техника' as name from dual
union all
select '2.1' as code, 'миксер' as name from dual
)
select * from t
code, sys_connect_by_path(name ,'.')
from t
connect by regexp_substr(code, '[^.]+', 1, level) -- какое-то хитрое условие соединения
...
Рейтинг: 0 / 0
13.12.2021, 14:19
    #40119645
zipperxz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Stax,

Добавил, буду очень признателен за помощь)
Что-то запутался в этой иерархии, как строку саму на себя рекурсивно подцепить...
Можно в условие брать соединение по подстроке, но тогда prior непонятно как использовать..
...
Рейтинг: 0 / 0
13.12.2021, 14:39
    #40119649
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with t as(
          select '1.2.1' as code, 'дверца' as name from dual union all
          select '1.2' as code, 'шкаф' as name from dual union all
          select '1' as code, 'мебель домашняя' as name from dual union all
          select '2' as code, 'бытовая техника' as name from dual union all
          select '2.1' as code, 'миксер' as name from dual
         )
select  sys_connect_by_path(name,'-->') path
  from  t
  start with instr(code,'.') = 0
  connect by code like prior code || '.%'
         and instr(code,'.',length(prior code) + 2) = 0
/



SY.
...
Рейтинг: 0 / 0
13.12.2021, 14:41
    #40119651
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
zipperxz,
Код: 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.
SQL> ed
Wrote file afiedt.buf

  1  with t as(
  2  select '1.2.1' as code, 'дверца' as name from dual
  3  union all
  4  select '1.2' as code, 'шкаф' as name from dual
  5  union all
  6  select '1' as code, 'мебель домашняя' as name from dual
  7  union all
  8  select '2' as code, 'бытовая техника' as name from dual
  9  union all
 10  select '2.1' as code, 'миксер' as name from dual
 11  )
 12  ,tt as (select  t.*,'.'||trim ('.' from code)||'.' c from t)
 13  select
 14    code
 15   ,lpad(' ',(level-1)*2)||name n
 16   ,sys_connect_by_path(name ,'.') p
 17  from tt
 18    start with instr(code,'.')=0
 19*   connect by substr(c,1,instr(c,'.',-1,2)) = prior c
SQL> /

CODE  N                    P
----- -------------------- ------------------------------
1     мебель домашняя      .мебель домашняя
1.2     шкаф               .мебель домашняя.шкаф
1.2.1     дверца           .мебель домашняя.шкаф.дверца
2     бытовая техника      .бытовая техника
2.1     миксер             .бытовая техника.миксер

SQL>



.....
stax
...
Рейтинг: 0 / 0
13.12.2021, 14:42
    #40119652
Алымов Анатолий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with t as(
select '1.2.1' as code, 'дверца' as name from dual
union all
select '1.2' as code, 'шкаф' as name from dual
union all
select '1' as code, 'мебель домашняя' as name from dual
union all
select '2' as code, 'бытовая техника' as name from dual
union all
select '2.1' as code, 'миксер' as name from dual
)
select t.*, ltrim(sys_connect_by_path(name ,'.'),'.')
from t
START WITH instr(code,'.')=0
connect by nocycle prior code=nvl(substr(code, 1, instr(code,'.',-1)-1),code)
...
Рейтинг: 0 / 0
13.12.2021, 14:46
    #40119653
zipperxz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Алымов Анатолий, SY, Stax,

Спасибо Вам огромное, гуру SQL, очень помогли разобраться!!!

Скажите, пжлста, что почитать на эту тему, где так хорошо объясняется этот рекурсивный запрос, что вы с такой легкостью решили?
...
Рейтинг: 0 / 0
13.12.2021, 21:58
    #40119760
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Гури, вы там прикалываетесь?
Это жеж классический классификатор.
Для работы с ним иерархические запросы не нужны.
Совсем не нужны.
Код: 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.
with t as(
select '1.2.1' as code, 'дверца' as name from dual
union all
select '1.2' as code, 'шкаф' as name from dual
union all
select '1' as code, 'мебель домашняя' as name from dual
union all
select '2' as code, 'бытовая техника' as name from dual
union all
select '2.1' as code, 'миксер' as name from dual
)
select code, name
from t
order by code
/

CODE  NAME
----- -----------------------------
1     мебель домашняя
1.2   шкаф
1.2.1 дверца
2     бытовая техника
2.1   миксер


-- Берем поддерево:
select code, name
from t
WHERE code like '1.%'
order by code
/

CODE  NAME
----- -----------------------------
1.2   шкаф
1.2.1 дверца

SQL> 
...
Рейтинг: 0 / 0
13.12.2021, 23:30
    #40119780
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
andrey_anonymous
Гури, вы там прикалываетесь?
Это жеж классический классификатор.
Для работы с ним иерархические запросы не нужны.
Совсем не нужны.


И как это дает "полный путь для каждого уровня (мебель>шкаф>дверца...)" по имени а не полный путь для каждого уровня 1.2.1 по коду?

SY.
...
Рейтинг: 0 / 0
14.12.2021, 01:24
    #40119784
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
+ rtrim
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with t as(
          select '1.2.1' as code, 'дверца' as name from dual union all
          select '1.2' as code, 'шкаф' as name from dual union all
          select '1' as code, 'мебель домашняя' as name from dual union all
          select '2' as code, 'бытовая техника' as name from dual union all
          select '2.1' as code, 'миксер' as name from dual
         )
select
  code, sys_connect_by_path(name ,'/') spath
from t
start with instr(code,'.')=0
connect by
  --rtrim(code, '1234567890') = prior code||'.'
    rtrim(rtrim(code, '1234567890'),'.') = prior code
order siblings by code
/

output
Код: 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.
SQL> ;
  1  with t as(
  2            select '1.2.1' as code, 'дверца' as name from dual union all
  3            select '1.2' as code, 'шкаф' as name from dual union all
  4            select '1' as code, 'мебель домашняя' as name from dual union all
  5            select '2' as code, 'бытовая техника' as name from dual union all
  6            select '2.1' as code, 'миксер' as name from dual
  7           )
  8  select
  9    code, sys_connect_by_path(name ,'/') spath
 10  from t
 11  start with instr(code,'.')=0
 12  connect by --rtrim(code, '1234567890') = prior code||'.'
 13  rtrim(rtrim(code, '1234567890'),'.') = prior code
 14* order siblings by code
SQL> /

CODE  SPATH
----- ----------------------------------------
1     /мебель домашняя
1.2   /мебель домашняя/шкаф
1.2.1 /мебель домашняя/шкаф/дверца
2     /бытовая техника
2.1   /бытовая техника/миксер

...
Рейтинг: 0 / 0
14.12.2021, 09:33
    #40119831
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
andrey_anonymous

Совсем не нужны.


етого мало, нужно еще и "выравнивание"
1.1
11.1
2.1

ps
авторГури, вы там прикалываетесь?
с точками я переборщил (прокололся ),
начал делать с like и перестраховался

....
stax
...
Рейтинг: 0 / 0
14.12.2021, 13:39
    #40119935
zipperxz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Connect by
Sayan Malakshinov,

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


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