powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / иерархия и регулярные выражения
11 сообщений из 11, страница 1 из 1
иерархия и регулярные выражения
    #39901236
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго времени суток!

Если есть возможность, подскажите, пожалуйста, как выйти из проблемы с решением задачи:
Дана таблица из двух столбцов ACTION и CODE, в каждом из которых хранятся списки чисел, разделённых пробелами. Создать запрос для разделения данных.
например, для таблицы
actioncode1000 1100.10 900841000 841100 841111700 500 400 4 923400 923411
Результат должен быть:
n_list n_posactioncode101000 1100.10 900 841000 841100 841111 11000841000 21100.10841100 390084111120700 500 400 4923400 923411 1700923400 2500923411 3400 44
В результате выборки приняты обозначения: N_LIST — порядковый номер списка в исходной таблице, N_POS — порядковый номер числа в списке.
Основным из условий решения задачи также является - невозможность использования аналитических функций и sys_guid.

привожу свое решение(до куда оно дошло):
Код: 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.
with tbl as (
             select '1000 1100.10 900' action, '841000 841100 841111' code from dual union all
             select '700 500 400 4', '923400 923411' from dual
            ),
       t as (
             select  rownum rn,
                     action,
                     code
               from  tbl
            )
select nvl(to_char((case level
          when 1 then rn
        end)),' ') n_list,
        level - 1 n_pos,
        nvl(to_char((case level
          when 1 then action
          else regexp_substr(action,'\d+(\.?\,?\d+)?',1,level-1)
        end)),' ') action,
        nvl(to_char((case level
          when 1 then code
          else regexp_substr(code,'\d+(\.?\,?\d+)?',1,level-1)
        end)), ' ') code
  from  t
  connect by  level <= greatest(nvl(regexp_count(action,' '),0),nvl(regexp_count(code,' '),0)) + 2       
  order by rn,level;



Проблема в том, что такой вариант выводит большое количество дублей. Пример вывода для первого набора значений:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
N_LIST                                        N_POS ACTION           CODE                
---------------------------------------- ---------- ---------------- --------------------
1                                                 0 1000 1100.10 900 841000 841100 841111
                                                  1 1000             841000              
                                                  1 1000             841000              
                                                  2 1100.10          841100              
                                                  2 1100.10          841100              
                                                  2 1100.10          841100              
                                                  2 1100.10          841100              
                                                  3 900              841111              
                                                  3 900              841111              
                                                  3 900              841111              
                                                  3 900              841111              

N_LIST                                        N_POS ACTION           CODE                
---------------------------------------- ---------- ---------------- --------------------
                                                  3 900              841111              
                                                  3 900              841111              
                                                  3 900              841111              
                                                  3 900              841111              

Подскажите, пожалуйста, как из них выбрать нужные строки с сохранением сортировки.
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901263
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select n_list
     , n_pos
     , case n_pos when 0 then action else regexp_substr(action, '\S+', 1, n_pos) end as action
     , case n_pos when 0 then code   else regexp_substr(code  , '\S+', 1, n_pos) end as code
  from (select rownum as n_list, tbl.* from tbl)
       cross apply
       ( select level - 1 as n_pos
           from dual
           connect by level -1 <= greatest(regexp_count(action, '\S+'), regexp_count(code, '\S+'))
       )

12с
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901275
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic, а есть ли возможность сделать без cross apply, насколько я понимаю, появился он только в 12с, у нас же курс по 11g
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901285
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic, и спасибо вам огромное и за это!)
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901286
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kochhar
Elic, а есть ли возможность сделать без cross apply, насколько я понимаю, появился он только в 12с, у нас же курс по 11g



Код: 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.
select  case level when 1 then dense_rank() over(order by rowid) end n_list,
        case level when 1 then action else regexp_substr(action,'[^ ]+',1,level - 1) end action,
        case level when 1 then code else regexp_substr(code,'[^ ]+',1,level - 1) end code
  from  tbl
  connect by rowid = prior rowid
         and prior sys_guid() is not null
         and level <= greatest(regexp_count(action,'[^ ]+'),regexp_count(code,'[^ ]+')) + 1
  order by rowid,
           level
/

    N_LIST ACTION               CODE
---------- -------------------- --------------------
         1 1000 1100.10 900     841000 841100 841111
           1000                 841000
           1100.10              841100
           900                  841111
         2 700 500 400 4        923400 923411
           700                  923400
           500                  923411
           400
           4

9 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901289
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пропустил n_pos:

Код: 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.
select  case level when 1 then dense_rank() over(order by rowid) end n_list,
        level - 1 n_pos,
        case level when 1 then action else regexp_substr(action,'[^ ]+',1,level - 1) end action,
        case level when 1 then code else regexp_substr(code,'[^ ]+',1,level - 1) end code
  from  tbl
  connect by rowid = prior rowid
         and prior sys_guid() is not null
         and level <= greatest(regexp_count(action,'[^ ]+'),regexp_count(code,'[^ ]+')) + 1
  order by rowid,
           level
/

    N_LIST      N_POS ACTION               CODE
---------- ---------- -------------------- --------------------
         1          0 1000 1100.10 900     841000 841100 841111
                    1 1000                 841000
                    2 1100.10              841100
                    3 900                  841111
         2          0 700 500 400 4        923400 923411
                    1 700                  923400
                    2 500                  923411
                    3 400
                    4 4

9 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901290
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kochhar
у нас же курс
Студент, а с претензиями.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
…
( select rownum
       , 0
       , action
       , code
       , action
       , code
    from tbl
  union all
  select n_list
       , n_pos + 1
       , regexp_substr(action0, '\S+', 1, n_pos + 1)
       , regexp_substr(code0  , '\S+', 1, n_pos + 1)
       , action0
       , code0
    from t
    where n_pos < greatest(regexp_count(action0, '\S+'), regexp_count(code0, '\S+'))
)
select n_list, n_pos, action, code
  from t
  order by 1, 2

Первая строчка останется тебе в качестве домашнего задания.
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901292
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
Пропустил
Редактирование своих сообщений по горячим следам доступно всем…
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901303
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, прочитал по-диагонали. Иерархия без "использования аналитических функций и sys_guid":

Код: 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.
with t1 as (
            select  level - 1 n_pos
              from  dual
              connect by level <= (
                                   select max(greatest(regexp_count(action,'[^ ]+'),regexp_count(code,'[^ ]+'))) + 1
                                    from  tbl
                                  )
           ),
     t2 as (
            select  rownum rn,
                    action,
                    code,
                    greatest(regexp_count(action,'[^ ]+'),regexp_count(code,'[^ ]+')) cnt
              from  tbl
           )
select  case n_pos when 0 then rn end n_list,
        n_pos,
        case n_pos when 0 then action else regexp_substr(action,'[^ ]+',1,n_pos) end action,
        case n_pos when 0 then code else regexp_substr(code,'[^ ]+',1,n_pos) end code
  from  t1,
        t2
  where n_pos <= cnt
  order by rn,
           n_pos
/

    N_LIST      N_POS ACTION               CODE
---------- ---------- -------------------- --------------------
         1          0 1000 1100.10 900     841000 841100 841111
                    1 1000                 841000
                    2 1100.10              841100
                    3 900                  841111
         2          0 700 500 400 4        923400 923411
                    1 700                  923400
                    2 500                  923411
                    3 400
                    4 4

9 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901309
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic, Ни в коем случае не претензия, извините, если звучало некорректно. Про rownum знаю, за вариант решения благодарю!)
...
Рейтинг: 0 / 0
иерархия и регулярные выражения
    #39901311
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY, Благодарю!
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / иерархия и регулярные выражения
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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