Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Создание наборов с помощью запроса / 21 сообщений из 21, страница 1 из 1
24.10.2019, 23:59
    #39881283
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Добрый вечер! Очень нужна помощь специалистов по работе с Oracle PL/SQL. Есть следующая задача. На входе имеем строку следующего типа [1]=[30];[2,3]>[4,5];[100,200]<[1,2,3];.....[]. Длина строки за ранее не известна. С этой строки необходимо получить перечень наборов следующего типа:
Пример в приложение.

перебираем все варианты. по такому принципу. Может кто то сталкивался или возможно у кого то есть какой алгоритм, как реализовать данную задачу.

Очень буду благодарен за помощь.
...
Рейтинг: 0 / 0
25.10.2019, 00:44
    #39881286
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991,

Код: 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.
SQL> with t(str) as
  2   (select '[1]=[30];[2,3]>[4,5];[100,200]<[1,2,3]' from dual)
  3  select sys_connect_by_path(sl.l || '=' || sr.r, ' ') x
  4  from
  5  (
  6  select rownum id,
  7         regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2 - 1, null, 1) l,
  8         regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2, null, 1) r
  9    from t
 10  connect by level < regexp_count(str, ';') + 2
 11  )
 12   cross apply (select regexp_substr(l, '\d+', 1, level) l from dual connect by level <= regexp_count(l, ',') + 1) sl
 13   cross apply (select regexp_substr(r, '\d+', 1, level) r from dual connect by level <= regexp_count(r, ',') + 1) sr
 14   where connect_by_isleaf = 1
 15   start with id = 1
 16  connect by prior id + 1 = id;

X
--------------------------------------------------------------------------------
 1=30 2=4 100=1
 1=30 2=4 100=2
 1=30 2=4 100=3
 1=30 2=4 200=1
 1=30 2=4 200=2
 1=30 2=4 200=3
 1=30 2=5 100=1
 1=30 2=5 100=2
 1=30 2=5 100=3
 1=30 2=5 200=1
 1=30 2=5 200=2
 1=30 2=5 200=3
 1=30 3=4 100=1
 1=30 3=4 100=2
 1=30 3=4 100=3
 1=30 3=4 200=1
 1=30 3=4 200=2
 1=30 3=4 200=3
 1=30 3=5 100=1
 1=30 3=5 100=2
 1=30 3=5 100=3
 1=30 3=5 200=1
 1=30 3=5 200=2
 1=30 3=5 200=3

24 rows selected.
...
Рейтинг: 0 / 0
25.10.2019, 10:42
    #39881390
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Кобанчег, добрый день! При запуске данного запроса выдает ошибку ora-00904: r invalid identifier.
Версия oracle 11g enterprise edition release 11.2.0.4.0.
...
Рейтинг: 0 / 0
25.10.2019, 11:24
    #39881421
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991,

на 11.2 этот запрос не взлетит
...
Рейтинг: 0 / 0
25.10.2019, 11:43
    #39881436
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
env, добрый день! Возможно у Вас есть идеи как это можно реализовать на версии 11.2?
...
Рейтинг: 0 / 0
25.10.2019, 12:01
    #39881451
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991Возможно у Вас естьНо ведь идея была показана.
Возможно стоит переформулировать вопрос: "Я даже не пытаюсь думать, сделайте всё за меня".
А не идеи спрашивать и алгоритмы.
...
Рейтинг: 0 / 0
25.10.2019, 12:07
    #39881462
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Кобанчег, я попробыл сделать вот такой вариант
Код: 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.
with t(str) as
   (select '[1]=[30];[2,3]>[4,5]' from dual),
   
 tt as (
 select rownum idlvl0,
         regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2 - 1, null, 1) l,
         regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2, null, 1) r
     from t 
      connect by level < regexp_count(str, ';') + 2
      )--,
      --select * from tt
     
      
      
      
      select distinct  sys_connect_by_path(sl.l || '=' || sr.r, ' ') x
   from  (select rownum idlvl0,
          regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2 - 1, null, 1) l,
          regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2, null, 1)           
         from t 
         connect by level < regexp_count(str, ';') + 2) t
      
   cross join  (select regexp_substr(l, '\d+', 1, level) l from tt connect by level <= regexp_count(l, ',') + 1) sl
   cross join (select regexp_substr(r, '\d+', 1, level) r from tt connect by level <= regexp_count(r, ',') + 1) sr
    where connect_by_isleaf = 1
    start with  idlvl0 = 1
    connect by prior  idlvl0 + 1 =  idlvl0
    order by 1


но это не работает , так как у вас. Я пока не особо силен в знании специфических вещей в Oracle. Мне не понятно пока, как можно отсеять не нужные данный
...
Рейтинг: 0 / 0
25.10.2019, 12:09
    #39881465
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
я уже неделю бьюсь над решением этой задачи и пока без успешно. А руководство требует решений, по этому и прошу о помощи
...
Рейтинг: 0 / 0
25.10.2019, 12:16
    #39881474
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991Я пока не особо силен в знании специфических вещей в Oracle.Ну раз ты тогадался, что дело в cross apply найди способ размножить строки без него.
Для этого не надо коверкать весь запрос, пихать туда distinct и прочее.

Ты вообще не объяснил зачем тебе это надо.
И какой смысл использовать код если ты не в состоянии его понять и поддерживать.
...
Рейтинг: 0 / 0
25.10.2019, 12:24
    #39881486
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991я уже неделю бьюсь над решением этой задачи и пока без успешно. А руководство требует решений, по этому и прошу о помощиТы просил идею или алгоритм.
Это можно было предоставить тебе в словесной форме.

Вместо этого был предоставлен конкретный код, работающий на 12c+.
И даже тут ты не в состянии сделать минимальное изменение.

Вместо хаотических маразматических изменений общего запроса подумай как можно переписать запрос ниже без cross apply.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SQL> with t(str) as (select '100,200' from dual)
  2  select x
  3    from t
  4   cross apply (select regexp_substr(str, '\d+', 1, level) x
  5                  from t
  6                connect by level <= regexp_count(str, ',') + 1);

X
----------------------------
100
200

Можно даже не думать, а воспользоваться поиском по форуму.
...
Рейтинг: 0 / 0
25.10.2019, 12:25
    #39881492
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Кобанчег, Задача следующаю - мне приходит ексель с набором полей. В ячейках екселя хранятся вот такие наборы разной длины и с разными условиями. Мне необходимо эти наборы натравить на запрос с базисными данными и получить выходной результат. Я c Oracle работаю пару месяцев, до этого 6 лет работал с ms sql. думаю как то разберусь с поддерживанием кода. А про специфические вещи - я имею ввиду например start with idlvl0 = 1 connect by prior idlvl0 + 1 = idlvl0 , которые я пока полностью не изучил (изучаю по необходимости).

Спасибо большое за помощь и идею. Буду дальше доделывать запрос
...
Рейтинг: 0 / 0
25.10.2019, 12:33
    #39881499
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991Я c Oracle работаю пару месяцев, до этого 6 лет работал с ms sql. думаю как то разберусь с поддерживанием кода. А про специфические вещи - я имею ввиду например start with idlvl0 = 1 connect by prior idlvl0 + 1 = idlvl0 , которые я пока полностью не изучилТогда должен суметь перебрать все варинты с помощью Recursive CTE вместо connect by.
...
Рейтинг: 0 / 0
25.10.2019, 12:34
    #39881500
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
КобанчегСергей_1991я уже неделю бьюсь над решением этой задачи и пока без успешно. А руководство требует решений, по этому и прошу о помощиТы просил идею или алгоритм.
Это можно было предоставить тебе в словесной форме.

Вместо этого был предоставлен конкретный код, работающий на 12c+.
И даже тут ты не в состянии сделать минимальное изменение.

Вместо хаотических маразматических изменений общего запроса подумай как можно переписать запрос ниже без cross apply.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SQL> with t(str) as (select '100,200' from dual)
  2  select x
  3    from t
  4   cross apply (select regexp_substr(str, '\d+', 1, level) x
  5                  from t
  6                connect by level <= regexp_count(str, ',') + 1);

X
----------------------------
100
200

Можно даже не думать, а воспользоваться поиском по форуму.


Поверьте, как распарсить строки я написал еще в первый день как получил задачу. У меня проблему составило перемножить и получить наборы. У меня не было идее как выбирать данные из набор и брать только одно значение.
...
Рейтинг: 0 / 0
25.10.2019, 12:35
    #39881502
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991мне приходит ексель с набором полей

Раз тебе приходит эксель, так парсь эти наборы средствами экселя и не морщь моск оракулу,
которые для этого не предназначен.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25.10.2019, 12:38
    #39881506
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Dimitry SibiryakovСергей_1991мне приходит ексель с набором полей

Раз тебе приходит эксель, так парсь эти наборы средствами экселя и не морщь моск оракулу,
которые для этого не предназначен.


Ексель может быть большой. И если начинать парсить в нем , может просто все зависнуть.
...
Рейтинг: 0 / 0
25.10.2019, 12:44
    #39881508
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991если начинать парсить в нем , может просто все зависнуть.

А может и не зависнуть. Всё дело в волшебных пузырьках руках программиста.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25.10.2019, 12:44
    #39881511
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Сергей_1991Поверьте, как распарсить строки я написал еще в первый день как получил задачу.Если б ты понимал, то не показывал бы то уродство с cross join.
...
Рейтинг: 0 / 0
25.10.2019, 13:46
    #39881564
Misha111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Код: 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.
with t(str) as
 (select '[1]=[30];[2,3]>[4,5];[100,200]<[1,2,3]' from dual)
, a as (
select rownum id,
       regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2 - 1, null, 1) l,
       regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2, null, 1) r
  from t
connect by level < regexp_count(str, ';') + 2
)
, sl as (
select distinct id,
       regexp_substr(l, '\d+', 1, level) l
from a
connect by level <= regexp_count(l, ',') + 1
)
, sr as (
select distinct id,
       regexp_substr(r, '\d+', 1, level) r
from a
connect by level <= regexp_count(r, ',') + 1
)
--select *
select sys_connect_by_path(sl.l || '=' || sr.r, ' ') x
from a, sl, sr
where a.id=sl.id and a.id=sr.id
and connect_by_isleaf = 1
 start with a.id = 1
connect by prior a.id + 1 = a.id;
...
Рейтинг: 0 / 0
25.10.2019, 13:49
    #39881569
Misha111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
если "влоб" переписать запрос Кобанчег`а наверно получится так
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
with t(str) as
 (select '[1]=[30];[2,3]>[4,5];[100,200]<[1,2,3]' from dual)
select sys_connect_by_path(sl.COLUMN_VALUE || '=' || sr.COLUMN_VALUE, ' ') x
--select *
from
(
select rownum id,
       regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2 - 1, null, 1) l,
       regexp_substr(str, '\[([[:digit:],]+)\]', 1, level * 2, null, 1) r
  from t
connect by level < regexp_count(str, ';') + 2
),
-- cross apply (select regexp_substr(l, '\d+', 1, level) l from dual connect by level <= regexp_count(l, ',') + 1) sl
 table(cast(multiset(select regexp_substr(l, '\d+', 1, level) l from dual connect by level <= regexp_count(l, ',') + 1) as sys.odcivarchar2list)) sl,
 table(cast(multiset(select regexp_substr(r, '\d+', 1, level) r from dual connect by level <= regexp_count(r, ',') + 1) as sys.odcivarchar2list)) sr
 where connect_by_isleaf = 1
 start with id = 1
connect by prior id + 1 = id;
...
Рейтинг: 0 / 0
25.10.2019, 15:12
    #39881621
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Кобанчег, спасибо за помощь, все получилось! Очень помог Ваш вариант решения, чтобы разобраться в логике как перемножать!
...
Рейтинг: 0 / 0
25.10.2019, 15:14
    #39881623
Сергей_1991
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание наборов с помощью запроса
Misha111, спасибо большое, только увидел Ваше решение, проверил, тоже подходит. Спасибо за помощь!
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Создание наборов с помощью запроса / 21 сообщений из 21, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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