Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Рекурсия и результат / 7 сообщений из 7, страница 1 из 1
31.01.2020, 14:45
    #39921016
AXEL_111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсия и результат
Доброго времени суток.
Столкнулся с рекурсией и не могу сообразить как корректно написать запрос, когда нужно отобразить определенные ветки дерева.

Нужно увидеть перемещение товара между объектами (есть имя первого объекта и последнего объекта, пример otpravitel = 'Склад_9' и poluchatel = 'Склад_3'), надо чтобы отображались все ветки с промежуточным звеном где есть такое совпадение.

Есть входные данные:

Код: 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 t (otpravitel, poluchatel, tovar) as (

select 'Склад_1', 'Магазин 4', 'Товар 5' from dual union 
select 'Склад_1', 'Магазин 7', 'Товар 3' from dual union 
select 'Склад_7', 'Магазин 6', 'Товар 8' from dual union 
select 'Склад_3', 'Магазин 5', 'Товар 9' from dual union 
select 'Склад_2', 'Магазин 5', 'Товар 9' from dual union 
select 'Магазин 7', 'Склад_7', 'Товар 7' from dual union 
select 'Магазин 5', 'Склад_3', 'Товар 4' from dual union 
select 'Магазин 4', 'Склад_2', 'Товар 6' from dual union 
select 'Склад_4', 'Склад_9', 'Товар 6' from dual union 
select 'Склад_9', 'Склад_2', 'Товар 2' from dual union 
select 'Склад_10', 'Магазин 6', 'Товар 5' from dual union 
select 'Склад_4', 'Склад_8', 'Товар 8' from dual union 
select 'Магазин 4', 'Магазин 9', 'Товар 9' from dual union 
select 'Магазин 9', 'Магазин 5', 'Товар 5' from dual union 
select 'Магазин 1', 'Магазин 4', 'Товар 5' from dual union 
select 'Магазин 5', 'Склад_10', 'Товар 6' from dual union 
select 'Магазин 4', 'Склад_1', 'Товар 5' from dual
)

select *
        from
(select level lvl, aa.otpravitel, aa.poluchatel,
        (connect_by_root aa.otpravitel)||sys_connect_by_path(aa.poluchatel, ' --> ') path

        from
(SELECT a.otpravitel, a.poluchatel
        FROM t a
group by a.otpravitel, a.poluchatel
) aa
connect by nocycle prior poluchatel=otpravitel  and level <= 4
start with otpravitel = 'Склад_9'
) aa
;



После выполнения запроса отображается результат:
LVL OTPRAVITEL POLUCHATEL PATH 1 Склад_9 Склад_2 Склад_9 --> Склад_2 2 Склад_2 Магазин 5 Склад_9 --> Склад_2 --> Магазин 5 3 Магазин 5 Склад_10 Склад_9 --> Склад_2 --> Магазин 5 --> Склад_10 4 Склад_10 Магазин 6 Склад_9 --> Склад_2 --> Магазин 5 --> Склад_10 --> Магазин 6 3 Магазин 5 Склад_3 Склад_9 --> Склад_2 --> Магазин 5 --> Склад_3

Как можно корректно (и можно ли так) задать условие выбора, чтобы отобразить всю цепочку связи (между otpravitel = 'Склад_9' и poluchatel = 'Склад_3'.
Желаемый результат ниже)?

LVL OTPRAVITEL POLUCHATEL PATH1 Склад_9 Склад_2 Склад_9 --> Склад_22 Склад_2 Магазин 5 Склад_9 --> Склад_2 --> Магазин 53 Магазин 5 Склад_3 Склад_9 --> Склад_2 --> Магазин 5 --> Склад_3

Заранее благодарю.
...
Рейтинг: 0 / 0
31.01.2020, 14:57
    #39921019
ln123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсия и результат
AXEL_111,

Навскидку можно как то так

Код: 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.
with t (otpravitel, poluchatel, tovar) as (

select 'Склад_1', 'Магазин 4', 'Товар 5' from dual union 
select 'Склад_1', 'Магазин 7', 'Товар 3' from dual union 
select 'Склад_7', 'Магазин 6', 'Товар 8' from dual union 
select 'Склад_3', 'Магазин 5', 'Товар 9' from dual union 
select 'Склад_2', 'Магазин 5', 'Товар 9' from dual union 
select 'Магазин 7', 'Склад_7', 'Товар 7' from dual union 
select 'Магазин 5', 'Склад_3', 'Товар 4' from dual union 
select 'Магазин 4', 'Склад_2', 'Товар 6' from dual union 
select 'Склад_4', 'Склад_9', 'Товар 6' from dual union 
select 'Склад_9', 'Склад_2', 'Товар 2' from dual union 
select 'Склад_10', 'Магазин 6', 'Товар 5' from dual union 
select 'Склад_4', 'Склад_8', 'Товар 8' from dual union 
select 'Магазин 4', 'Магазин 9', 'Товар 9' from dual union 
select 'Магазин 9', 'Магазин 5', 'Товар 5' from dual union 
select 'Магазин 1', 'Магазин 4', 'Товар 5' from dual union 
select 'Магазин 5', 'Склад_10', 'Товар 6' from dual union 
select 'Магазин 4', 'Склад_1', 'Товар 5' from dual
),
t2 as (
select *
        from
(select level lvl, aa.otpravitel, aa.poluchatel,
        (connect_by_root aa.otpravitel)||sys_connect_by_path(aa.poluchatel, ' --> ') path

        from
(SELECT a.otpravitel, a.poluchatel
        FROM t a
group by a.otpravitel, a.poluchatel
) aa
connect by nocycle prior poluchatel=otpravitel  and level <= 4
start with otpravitel = 'Склад_9'
) aa)

select * from t2 where exists (select * from t2 t3 where t3.poluchatel = 'Склад_3' and  t3.path like t2.path||'%') 
;
...
Рейтинг: 0 / 0
31.01.2020, 15:28
    #39921032
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсия и результат
AXEL_111
перемещение товара
В твоем запросе со склада выехал грузовик с огурцами, в магазин приехал с помидорами.
AXEL_111
чтобы отображались все ветки
Разверни path взад.
...
Рейтинг: 0 / 0
31.01.2020, 15:34
    #39921035
AXEL_111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсия и результат
-2-
AXEL_111
перемещение товара
В твоем запросе со склада выехал грузовик с огурцами, в магазин приехал с помидорами.
AXEL_111
чтобы отображались все ветки
Разверни path взад.


На данный момент какой товар выехал и какой заехал не важно, в поставленной задаче важно связь объекта с объектом.
...
Рейтинг: 0 / 0
31.01.2020, 20:45
    #39921177
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсия и результат
AXEL_111,
AXEL_111

На данный момент какой товар выехал и какой заехал не важно, в поставленной задаче важно связь объекта с объектом.



Начнемс того что у тебя иерархия не рекурсия. Ну и если в поставленной задаче важно связь объекта с объектом то:

Код: 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.
with t (otpravitel, poluchatel, tovar) as (
select 'Warehouse_1', 'Store 4', 'Product 5' from dual union 
select 'Warehouse_1', 'Store 7', 'Product 3' from dual union 
select 'Warehouse_7', 'Store 6', 'Product 8' from dual union 
select 'Warehouse_3', 'Store 5', 'Product 9' from dual union 
select 'Warehouse_2', 'Store 5', 'Product 9' from dual union 
select 'Store 7', 'Warehouse_7', 'Product 7' from dual union 
select 'Store 5', 'Warehouse_3', 'Product 4' from dual union 
select 'Store 4', 'Warehouse_2', 'Product 6' from dual union 
select 'Warehouse_4', 'Warehouse_9', 'Product 6' from dual union 
select 'Warehouse_9', 'Warehouse_2', 'Product 2' from dual union 
select 'Warehouse_10', 'Store 6', 'Product 5' from dual union 
select 'Warehouse_4', 'Warehouse_8', 'Product 8' from dual union 
select 'Store 4', 'Store 9', 'Product 9' from dual union 
select 'Store 9', 'Store 5', 'Product 5' from dual union 
select 'Store 1', 'Store 4', 'Product 5' from dual union 
select 'Store 5', 'Warehouse_10', 'Product 6' from dual union 
select 'Store 4', 'Warehouse_1', 'Product 5' from dual
),
t1 as (
       select distinct otpravitel, poluchatel from t
      ),
t2 as (
       select  cast(connect_by_root(otpravitel) || sys_connect_by_path(poluchatel,'-->') as varchar2(4000)) chain
         from  t1
         start with otpravitel = 'Warehouse_9'
         connect by nocycle otpravitel = prior poluchatel
                        and prior poluchatel != 'Warehouse_3'
      )
select  otpravitel,
        poluchatel,
        path
  from  t2,
        lateral(
                select  regexp_substr(chain,'[^->]+',1,level) otpravitel,
                        regexp_substr(chain,'[^->]+',1,level + 1) poluchatel,
                        substr(chain,1,instr(chain || '-->','-->',1,level + 1) - 1) path
                  from  dual
                  connect by level <= regexp_count(chain,'-->')
               )
  where chain like '%-->Warehouse_3'
/

OTPRAVITEL      POLUCHATEL      PATH
--------------- --------------- ------------------------------------------------------------
Warehouse_9     Warehouse_2     Warehouse_9-->Warehouse_2
Warehouse_2     Store 5         Warehouse_9-->Warehouse_2-->Store 5
Store 5         Warehouse_3     Warehouse_9-->Warehouse_2-->Store 5-->Warehouse_3

SQL>



SY.
...
Рейтинг: 0 / 0
31.01.2020, 23:08
    #39921223
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсия и результат
Забыл упомянуть - прдполагается символы '-' и '>' названиях отправителя и получателя не присутствуют.

SY.
...
Рейтинг: 0 / 0
04.02.2020, 18:07
    #39922444
AXEL_111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсия и результат
Огромное спасибо за помощь.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Рекурсия и результат / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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