Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Подскажите вариант решения задачки / 11 сообщений из 11, страница 1 из 1
13.08.2020, 21:09
    #39989553
Landgraf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Приветствую всех!

Подскажите, пожалуйста, варианты решения вот такой задачки:
Есть таблиц, состоящая из двух столбцов ID и CodeList. Id – идентификатор объекта, CodeList – список, в котором через запятую перечислены коды(буквы).
Суть задачи – для каждого идентификатора нужно разобрать его список на отдельные коды и вывести в виде таблицы.

Пример:
1 – A,B,C
2 – X,Y

На выходе должны получить:
Результат:1 A
1 B
1 C
2 X
2 Y

Моя идея была такова:
1) Разберем строку кода с помощью конструкции:
Код: plsql
1.
2.
  select RegExp_substr(CodeList,'\w+',1,level) as Code 
         from dual connect by RegExp_count(CodeList,',')+1>=level



Разбор строки возвращает нам результирующий набор из N строк, где N – это количество кодов в списке.
Далее хотелось бы соединить первую запись из таблицы со своим результатом разбора. Что-то типа этого.
Если б можно было по очереди передавать значение первой записи из таблицы во второй inline view, чтобы оно выполнилось, результат перемножился бы с первой таблицей и .д.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
With 
    Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual       
             )
             
    select E1.id, E2.Code from  Example E1, (select E1.id, RegExp_substr(E1.CodeList,'\w+',1,level) as Code 
                                             from dual connect by RegExp_count(E1.CodeList,',')+1>=level) E2         

           where E1.id = E2.id 



Но в таком варианте не работает, конечно.
Товарищи , какие вариантны можете подсказать для решение данной задачи?
...
Рейтинг: 0 / 0
13.08.2020, 21:27
    #39989561
Relic Hunter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Изучить 3 формы нормализации данных для начала. Вот смешно и все же. Работаю с учетной системой довольно большой и уважаемой конторы. Там так айдишники ссылочной сущности через запятую в стоковом поле и хранятся. Какие там запросы "летят" на сервер можете догадаться. Складывается общее впечатление, что "архитекторы" и не подозревали о правилах разраборки реляционных данных.
...
Рейтинг: 0 / 0
13.08.2020, 21:32
    #39989562
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Landgraf
не работает, конечно.

Ну отчего же не работает...
Код: 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> With
    Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual
             )
    select E1.id, E2.Code
      from  Example E1
         , lateral(select E1.id, RegExp_substr(E1.CodeList,'\w+',1,level) as Code
              from dual
           connect by RegExp_count(E1.CodeList,',')+1>=level
           ) E2
;
 
        ID CODE
---------- -----
         1 A
         1 B
         1 C
         2 X
         2 Y
 
SQL> 


А так вариантов много.
Простейший - иерархический запрос прямо над исходным набором.
...
Рейтинг: 0 / 0
13.08.2020, 21:43
    #39989567
Landgraf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
andrey_anonymous
Landgraf
не работает, конечно.


А так вариантов много.
Простейший - иерархический запрос прямо над исходным набором.



ТОЧНО!!!! Ведь понмнил, что была какая-то конструкция!!! andrey_anonymous +1 в карму!

Иерархические запроссы вещь мощная, но не постиг до конца!

Какие условие соединения/ограничения нужно добававить, чтобы через иерархический запрос решить:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
With 
    Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual       
             )
             
       select id, RegExp_substr(CodeList,'\w+',1,level) as Code  from Example 
              connect by RegExp_count(CodeList,',')+1> = level 
...
Рейтинг: 0 / 0
13.08.2020, 22:50
    #39989588
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Landgraf
Какие условие соединения/ограничения нужно добававить, чтобы через иерархический запрос решить:

Да обычные...
Код: 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.
With
    Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual
             )
select id, codelist
     , regexp_substr(codelist,'[^,]+',1,level)
  from example
connect by id = prior id
    and level <=regexp_count(codelist,',')+1
    and prior dbms_random.random is not null
;
 
        ID CODELIST REGEXP_SUBSTR(CODELIST,'[^,]+'
---------- -------- ------------------------------
         1 A,B,C    A
         1 A,B,C    B
         1 A,B,C    C
         2 X,Y      X
         2 X,Y      Y
 
SQL> 
...
Рейтинг: 0 / 0
13.08.2020, 23:27
    #39989605
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Вообще способов чуть более чем дофига.
Лишь некоторые еще не упомянутые:
Код: 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.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
SQL>
with     Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual
             )
, cte(id, code, codelist) as (
select id
     , regexp_substr(codelist,'[^,]+')
     , regexp_substr(codelist,',(.*)',1,1,null,1)
from example
union all
select id
     , regexp_substr(codelist,'[^,]+')
     , regexp_substr(codelist,',(.*)',1,1,null,1)
  from cte
 where codelist is not null
)SEARCH DEPTH FIRST BY id set orderval
select id, code
  from cte
;
 
        ID CODE
---------- -----
         1 A
         1 B
         1 C
         2 X
         2 Y
 
SQL>
with     Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual
             )
select id, code
from example
model
partition by (id)
dimension by (1 code#)
measures (codelist, ' ' code)
rules(code[for code# from 1 to regexp_count(codelist[1]||',',',') increment 1] = regexp_substr(codelist[1],'[^,]+',1,cv(code#)))
;
 
        ID CODE
---------- ----
         1 A
         1 B
         1 C
         2 X
         2 Y
 
SQL>
with     Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual
             )
select id, code
  from example e
     , xmltable(('"'||replace(e.CodeList,',','","')||'"')
                columns code varchar2(10) path '.');
 
        ID CODE
---------- ----------
         1 A
         1 B
         1 C
         2 X
         2 Y
;
...
Рейтинг: 0 / 0
14.08.2020, 06:51
    #39989641
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Landgraf
andrey_anonymous +1 в карму!
Да-да. За помощь в выстреливании себе в ногу.
...
Рейтинг: 0 / 0
14.08.2020, 06:57
    #39989642
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Relic Hunter
Изучить 3 формы нормализации данных для начала.

Шо это такое? Это нам не нужно, нам нужны крутые рекурсивные запросы в 5 этажей и крутые спецы, которые умеют их писать.
А нормализация, она зачем? В оракле есть connect by, значит можно писать id через запятую, есть pivot, значит можно делать везде eav.
...
Рейтинг: 0 / 0
14.08.2020, 14:29
    #39989831
Landgraf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Вот, еще вот такможно:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
With 
    Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual       
             )
    
     select id, column_value  from Example E1, 
              table(CAST(multiset(select RegExp_substr(E1.CodeList,'\w+',1,level) 
                                         from dual connect by RegExp_count(E1.CodeList,',')+1>=level) as 
                                         SYS.Odcivarchar2list                                        
                                         ))

ID	COLUMN_VALUE
1	A
1	B
1	C
2	X
2	Y
...
Рейтинг: 0 / 0
14.08.2020, 15:25
    #39989875
Landgraf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
andrey_anonymous
Landgraf
Какие условие соединения/ограничения нужно добававить, чтобы через иерархический запрос решить:

Да обычные...
Код: 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.
With
    Example (id, CodeList) as
            (
             select 1, 'A,B,C' from dual
             union all
             select 2, 'X,Y' from dual
             )
select id, codelist
     , regexp_substr(codelist,'[^,]+',1,level)
  from example
connect by id = prior id
    and level <=regexp_count(codelist,',')+1
    and prior dbms_random.random is not null
;
 
        ID CODELIST REGEXP_SUBSTR(CODELIST,'[^,]+'
---------- -------- ------------------------------
         1 A,B,C    A
         1 A,B,C    B
         1 A,B,C    C
         2 X,Y      X
         2 X,Y      Y
 
SQL> 



andrey_anonymous , а не подскажите для чего здесь вот это условие, что оно делает? Не могу никак понять

Код: plsql
1.
and prior dbms_random.random is not null
...
Рейтинг: 0 / 0
14.08.2020, 16:33
    #39989896
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант решения задачки
Landgraf
Не могу никак понять

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


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