powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Рекурсия и результат
7 сообщений из 7, страница 1 из 1
Рекурсия и результат
    #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
Рекурсия и результат
    #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
Рекурсия и результат
    #39921032
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AXEL_111
перемещение товара
В твоем запросе со склада выехал грузовик с огурцами, в магазин приехал с помидорами.
AXEL_111
чтобы отображались все ветки
Разверни path взад.
...
Рейтинг: 0 / 0
Рекурсия и результат
    #39921035
AXEL_111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-
AXEL_111
перемещение товара
В твоем запросе со склада выехал грузовик с огурцами, в магазин приехал с помидорами.
AXEL_111
чтобы отображались все ветки
Разверни path взад.


На данный момент какой товар выехал и какой заехал не важно, в поставленной задаче важно связь объекта с объектом.
...
Рейтинг: 0 / 0
Рекурсия и результат
    #39921177
Фотография 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
Рекурсия и результат
    #39921223
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл упомянуть - прдполагается символы '-' и '>' названиях отправителя и получателя не присутствуют.

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


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