powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Рекурсия: родитель + последний дочерний
10 сообщений из 10, страница 1 из 1
Рекурсия: родитель + последний дочерний
    #40038546
Hubertanyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток!
Есть такие структура данных:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
- родительский элемент1 // тип 1
  - элемент1
    - значение1
  - дочерний элемент1 // тип 1
    - элемент2
      - значение2
  - элемент3
    - значение3


В итоге нужно выбрать все дочерние значения (значение1, значение2, значение3) с привязкой к родителю. Т.е.

Код: html
1.
2.
3.
родительский элемент1 - значение1
дочерний элемент1  - значение2
родительский элемент1 - значение3




Выполняю такой запрос
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
WITH CTE (NAME, ID, ID_PARENT, ID_PACKAGE, NAME_PACKAGE) AS (
    SELECT T.NAME, T.ID, T.ID_PARENT, T.ID, T.NAME
    FROM TEST T
    WHERE ID_TYPE = 1
    UNION ALL
    SELECT T1.NAME, T1.ID, T1.ID_PARENT, CTE.ID_PACKAGE, CTE.NAME_PACKAGE
    FROM TEST T1
             INNER JOIN CTE ON T1.ID_PARENT = CTE.ID
)
SELECT *
FROM CTE
WHERE NOT EXISTS(SELECT 1 FROM TEST T2 WHERE T2.ID_PARENT = CTE.ID)
ORDER BY ID;



И в результате получаю
Код: html
1.
2.
3.
4.
родительский элемент1 - значение1
родительский элемент1 - значение2 // повтор значения для родительского элемента
дочерний элемент1  - значение2 // повтор значения для дочернего элемента
родительский элемент1 - значение3


Т.е. сейчас в результат попадают "значение2" как для родителя так и для дочернего. Как сделать выборку, чтобы в результат попадали значения дочерних элементов без повтора родительского элемента(т.е. значения последнего дочернего элемента )?
Например,

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
- родительский элемент1 // тип 1
  - элемент1
    - значение1
  - дочерний элемент1 // тип 1
    - элемент2
      - дочерний элемент2 // тип 1
        - значение2
  - элемент3
    - значение3



На выходе должно быть (запись вида "родительский элемент1 - значение2" не должна попасть в результат)
Код: html
1.
2.
3.
родительский элемент1 - значение1
дочерний элемент2  - значение2  
родительский элемент1 - значение3
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038564
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hubertanyan,

ити от листьев к тип 1

зы
данные в форме with не хотите набить

.....
stax
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038572
Hubertanyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
Hubertanyan,

ити от листьев к тип 1

зы
данные в форме with не хотите набить

.....
stax

Сама структура
Код: plsql
1.
2.
3.
4.
5.
6.
7.
create table TEST
(
    ID        NUMBER,
    NAME      VARCHAR2(50),
    ID_PARENT NUMBER,
    ID_TYPE   NUMBER
);



Данные
Код: plsql
1.
2.
3.
4.
5.
INSERT INTO TEST (ID, NAME, ID_PARENT, ID_TYPE) VALUES (1, '"111"', null, 1);
INSERT INTO TEST (ID, NAME, ID_PARENT, ID_TYPE) VALUES (2, '"222"', 1, 2);
INSERT INTO TEST (ID, NAME, ID_PARENT, ID_TYPE) VALUES (3, '"333"', 1, 2);
INSERT INTO TEST (ID, NAME, ID_PARENT, ID_TYPE) VALUES (4, '"444"', 1, 1);
INSERT INTO TEST (ID, NAME, ID_PARENT, ID_TYPE) VALUES (5, '"555"', 4, 2);



Результат такой:

NAMEIDID_PARENTID_PACKAGENAME_PACKAGE"222"211"111""333"311"111""555"544"444""555"541"111"

В итоге нужно получить:

NAMEIDID_PARENTID_PACKAGENAME_PACKAGE"222"211"111""333"311"111""555"544"444"
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038599
Hubertanyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax


ити от листьев к тип 1

А в этом случае не придем к тому же? На примере значения "значение2"
Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
- родительский элемент1 // тип 1
  - элемент1
    - значение1
  - дочерний элемент1 // тип 1
    - элемент2
      - дочерний элемент2 // тип 1
        - элемент3
          - значение2
  - элемент3
    - значение3


Приведет к результату

Код: html
1.
2.
3.
дочерний элемент2 - значение2
дочерний элемент1 - значение2
родительский элемент1 - значение2
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038619
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hubertanyan
Stax


ити от листьев к тип 1

А в этом случае не придем к тому же? На примере значения "значение2"


где with?

шот у меня с утра понедельника паршивое настроение


шаблон, не тестировал, просто схема
+ название колонок привести в порядок
лень доводить до ума
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
with t (ID, NAME, ID_PARENT, ID_TYPE) as (
select 1, '"111"', null, 1 from dual union all
select 2, '"222"', 1, 2 from dual union all
select 3, '"333"', 1, 2 from dual union all
select 4, '"444"', 1, 1 from dual union all
select 5, '"555"', 4, 2 from dual union all
select 6, '"666"', 5, 2 from dual)
,CTE (NAME, ID, ID_PARENT, ID_type,name_package,l,name_r,id_r)  AS (
    SELECT NAME, ID, ID_PARENT, ID_type, '' name_package,1 l,name,id
    FROM T
    WHERE not exists (select 1 from t e where e.id_parent=t.id)
    UNION ALL
    SELECT T.NAME, T.ID, T.ID_PARENT,t.id_type
            ,decode(t.id_type,1,t.name)
            ,cte.l+1
            ,cte.name_r
           ,cte.id_r
    FROM T T,CTE where cte.ID_PARENT = T.ID and cte.name_package is null
)
select id id_package,name_package, name_r name,id_r id from cte where name_package is not null
/



у with t добавляйте данные для тестирования, буду исправлять косяки
пока root type=1, листья type<>1

.....
stax
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038651
Hubertanyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
Hubertanyan
пропущено...

А в этом случае не придем к тому же? На примере значения "значение2"


где with?

шот у меня с утра понедельника паршивое настроение


шаблон, не тестировал, просто схема
+ название колонок привести в порядок
лень доводить до ума
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
with t (ID, NAME, ID_PARENT, ID_TYPE) as (
select 1, '"111"', null, 1 from dual union all
select 2, '"222"', 1, 2 from dual union all
select 3, '"333"', 1, 2 from dual union all
select 4, '"444"', 1, 1 from dual union all
select 5, '"555"', 4, 2 from dual union all
select 6, '"666"', 5, 2 from dual)
,CTE (NAME, ID, ID_PARENT, ID_type,name_package,l,name_r,id_r)  AS (
    SELECT NAME, ID, ID_PARENT, ID_type, '' name_package,1 l,name,id
    FROM T
    WHERE not exists (select 1 from t e where e.id_parent=t.id)
    UNION ALL
    SELECT T.NAME, T.ID, T.ID_PARENT,t.id_type
            ,decode(t.id_type,1,t.name)
            ,cte.l+1
            ,cte.name_r
           ,cte.id_r
    FROM T T,CTE where cte.ID_PARENT = T.ID and cte.name_package is null
)
select id id_package,name_package, name_r name,id_r id from cte where name_package is not null
/



у with t добавляйте данные для тестирования, буду исправлять косяки
пока root type=1, листья type<>1

.....
stax

Прошу прощения, изначально не все подробности описал - а если "id_type" может иметь несколько значений, например 1, 5, 7, 8..., которые "приходят" в запрос параметром.


Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
- родительский элемент1 // тип 1
  - элемент1
    - значение1
  - дочерний элемент1 // тип 5
    - элемент2
      - значение2
  - элемент3
    - значение3
  - дочерний элемент2 // тип 1
    - дочерний элемент3 // тип 5
      - элемент4
       - значение4



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with t (ID, NAME, ID_PARENT, ID_TYPE) as (
    select 1, '"111"', null, 1 from dual union all
    select 2, '"222"', 1, 2 from dual union all
    select 3, '"333"', 1, 2 from dual union all
    select 4, '"444"', 1, 5 from dual union all
    select 5, '"555"', 4, 2 from dual union all
    select 6, '"666"', 5, 2 from dual union all
    select 7, '"777"', 1, 1 from dual union all
    select 8, '"888"', 7, 5 from dual union all
    select 9, '"999"', 8, 2 from dual)
   ,CTE (NAME, ID, ID_PARENT, ID_type,name_package,l,name_r,id_r)  AS (
    SELECT NAME, ID, ID_PARENT, ID_type, '' name_package,1 l,name,id
    FROM T
    WHERE not exists (select 1 from t e where e.id_parent=t.id)
    UNION ALL
    SELECT T.NAME, T.ID, T.ID_PARENT,t.id_type
         ,decode(t.id_type,1,t.name)
         ,cte.l+1
         ,cte.name_r
         ,cte.id_r
    FROM T T,CTE where cte.ID_PARENT = T.ID and cte.name_package is null
)
select id id_package,name_package, name_r name,id_r id from cte where name_package is not null
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038660
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hubertanyan

Прошу прощения, изначально не все подробности описал - а если "id_type" может иметь несколько значений, например 1, 5, 7, 8..., которые "приходят" в запрос параметром.



не понял

Важен ж токо id_type=1

что не так?
Код: plsql
1.
2.
3.
4.
5.
6.
ID_PACKAGE NAME_ NAME          ID
---------- ----- ----- ----------
         1 "111" "333"          3
         1 "111" "222"          2
         7 "777" "999"          9
         1 "111" "666"          6



......
stax
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038665
Hubertanyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
Hubertanyan

Прошу прощения, изначально не все подробности описал - а если "id_type" может иметь несколько значений, например 1, 5, 7, 8..., которые "приходят" в запрос параметром.



не понял

Важен ж токо id_type=1

что не так?
Код: plsql
1.
2.
3.
4.
5.
6.
ID_PACKAGE NAME_ NAME          ID
---------- ----- ----- ----------
         1 "111" "333"          3
         1 "111" "222"          2
         7 "777" "999"          9
         1 "111" "666"          6




......
stax


Нет, не только id_type=1, может быть и другое значение типа из группы типов, которые передаются параметром, запрос будет такой

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
WITH CTE (NAME, ID, ID_PARENT, ID_PACKAGE, NAME_PACKAGE) AS (
    SELECT T.NAME, T.ID, T.ID_PARENT, T.ID, T.NAME
    FROM TEST T
    WHERE ID_TYPE IN( 1, 5, 7) -- переданная группа типов
    UNION ALL
    SELECT T1.NAME, T1.ID, T1.ID_PARENT, CTE.ID_PACKAGE, CTE.NAME_PACKAGE
    FROM TEST T1
             INNER JOIN CTE ON T1.ID_PARENT = CTE.ID
)
SELECT *
FROM CTE
WHERE NOT EXISTS(SELECT 1 FROM TEST T2 WHERE T2.ID_PARENT = CTE.ID)
ORDER BY ID;
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038676
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hubertanyan


Нет, не только id_type=1, может быть и другое значение типа из группы типов, которые передаются параметром, запрос будет такой


так задайте перечень (decode, in, instr ...)

так чтоли?
Код: 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.
SQL> ed
Wrote file afiedt.buf

  1  with t (ID, NAME, ID_PARENT, ID_TYPE) as (
  2      select 1, '"111"', null, 1 from dual union all
  3      select 2, '"222"', 1, 2 from dual union all
  4      select 3, '"333"', 1, 2 from dual union all
  5      select 4, '"444"', 1, 5 from dual union all
  6      select 5, '"555"', 4, 2 from dual union all
  7      select 6, '"666"', 5, 2 from dual union all
  8      select 7, '"777"', 1, 1 from dual union all
  9      select 8, '"888"', 7, 5 from dual union all
 10      select 9, '"999"', 8, 2 from dual)
 11     ,CTE (NAME, ID, ID_PARENT, ID_type,name_package,l,name_r,id_r)  AS (
 12      SELECT NAME, ID, ID_PARENT, ID_type, '' name_package,1 l,name,id
 13      FROM T
 14      WHERE not exists (select 1 from t e where e.id_parent=t.id)
 15      UNION ALL
 16      SELECT T.NAME, T.ID, T.ID_PARENT,t.id_type
 17           ,decode(t.id_type,1,t.name,5,t.name,7,t.name)    -- in ( 1, 5, 7)
 18           ,cte.l+1
 19           ,cte.name_r
 20           ,cte.id_r
 21      FROM T T,CTE where cte.ID_PARENT = T.ID and cte.name_package is null
 22  )
 23  select id id_package,name_package, name_r name,id_r id from cte where name_package is not null
 24  --select t.*,level,rpad(' ',level,' ')||name n,connect_by_isleaf
 25* --from t start with id_parent is null connect by id_parent=prior id
SQL> /

ID_PACKAGE NAME_ NAME          ID
---------- ----- ----- ----------
         1 "111" "333"          3
         1 "111" "222"          2
         8 "888" "999"          9
         4 "444" "666"          6

SQL>



....
stax
...
Рейтинг: 0 / 0
Рекурсия: родитель + последний дочерний
    #40038684
Hubertanyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
Hubertanyan


Нет, не только id_type=1, может быть и другое значение типа из группы типов, которые передаются параметром, запрос будет такой


так задайте перечень (decode, in, instr ...)

так чтоли?
Код: 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.
SQL> ed
Wrote file afiedt.buf

  1  with t (ID, NAME, ID_PARENT, ID_TYPE) as (
  2      select 1, '"111"', null, 1 from dual union all
  3      select 2, '"222"', 1, 2 from dual union all
  4      select 3, '"333"', 1, 2 from dual union all
  5      select 4, '"444"', 1, 5 from dual union all
  6      select 5, '"555"', 4, 2 from dual union all
  7      select 6, '"666"', 5, 2 from dual union all
  8      select 7, '"777"', 1, 1 from dual union all
  9      select 8, '"888"', 7, 5 from dual union all
 10      select 9, '"999"', 8, 2 from dual)
 11     ,CTE (NAME, ID, ID_PARENT, ID_type,name_package,l,name_r,id_r)  AS (
 12      SELECT NAME, ID, ID_PARENT, ID_type, '' name_package,1 l,name,id
 13      FROM T
 14      WHERE not exists (select 1 from t e where e.id_parent=t.id)
 15      UNION ALL
 16      SELECT T.NAME, T.ID, T.ID_PARENT,t.id_type
 17           ,decode(t.id_type,1,t.name,5,t.name,7,t.name)    -- in ( 1, 5, 7)
 18           ,cte.l+1
 19           ,cte.name_r
 20           ,cte.id_r
 21      FROM T T,CTE where cte.ID_PARENT = T.ID and cte.name_package is null
 22  )
 23  select id id_package,name_package, name_r name,id_r id from cte where name_package is not null
 24  --select t.*,level,rpad(' ',level,' ')||name n,connect_by_isleaf
 25* --from t start with id_parent is null connect by id_parent=prior id
SQL> /

ID_PACKAGE NAME_ NAME          ID
---------- ----- ----- ----------
         1 "111" "333"          3
         1 "111" "222"          2
         8 "888" "999"          9
         4 "444" "666"          6

SQL>



....
stax


Спасибо, попробую через

Код: plsql
1.
case when t.id_type in ( 1, 5, 7) then t.name end
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Рекурсия: родитель + последний дочерний
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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