Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Расшифровка кодов через запятую ("code1, code2" => "Name 1; Name 2") / 5 сообщений из 5, страница 1 из 1
06.09.2021, 11:44
    #40095438
g_andrew11
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расшифровка кодов через запятую ("code1, code2" => "Name 1; Name 2")
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0

Исходные данные:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with DEPT as (
   select 'a1' as DCODE, 'dept 1' as DNAME from dual union all
   select 'a2' as DCODE, 'dept 2' as DNAME from dual union all
   select 'a3' as DCODE, 'dept 3' as DNAME from dual
),
EPT as (
   select 'a2,a3'    as DCODES, 'ept 1' as ENAME from dual union all
   select 'a1' as DCODES, 'ept 2' as ENAME from dual union all
   select 'a3,a2' as DCODES, 'ept 3' as ENAME from dual
)



Нужно для каждого EPT через точку с запятой перечислить все его DEPT.
Но скрипт
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select e.ENAME,
       (select listagg(dd.DNAME, '; ') within group (order by dd.N)
            from (select d.DNAME, p.LVL as N--, e.DCODES, rownum
                    from (select level as LVL , regexp_substr(e.DCODES, '[^,]+', 1, level) as DCODE
                            from dual
                         connect by regexp_substr(e.DCODES, '[^,]+', 1, level) is not null) p
                    join DEPT d on d.DCODE = p.DCODE
                 ) dd
         ) as DNAMES      
  from EPT e


даёт неожиданный результат:

ENAMEDNAMESept 1dept 2; dept 3ept 2dept 2; dept 3ept 3dept 2; dept 3

Если раскоментировать
Код: plsql
1.
--, e.DCODES, rownum

, то получаем ожидаемый результат:
ENAMEDNAMESept 1dept 2; dept 3ept 2dept 1ept 3dept 3; dept 2

Почему??
...
Рейтинг: 0 / 0
06.09.2021, 14:12
    #40095481
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расшифровка кодов через запятую ("code1, code2" => "Name 1; Name 2")
g_andrew11

Почему??

имхо, оптимизатор дооптимизировался

ps
попробовать lateral (не помню был ли в 12-ке)

.....
stax
...
Рейтинг: 0 / 0
06.09.2021, 14:33
    #40095486
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расшифровка кодов через запятую ("code1, code2" => "Name 1; Name 2")
g_andrew11,

Код фтопку:

Код: 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 dept as (
              select 'a1' as dcode, 'dept 1' as dname from dual union all
              select 'a2' as dcode, 'dept 2' as dname from dual union all
              select 'a3' as dcode, 'dept 3' as dname from dual
             ),
     ept as (
             select 'a2,a3' as dcodes, 'ept 1' as ename from dual union all
             select 'a1'    as dcodes, 'ept 2' as ename from dual union all
             select 'a3,a2' as dcodes, 'ept 3' as ename from dual
            )
select  e.ename,
        listagg(d.dname, '; ') within group (order by instr(',' || e.dcodes || ',',',' || d.dcode || ',')) dnames
  from  ept e,
        dept d
  where instr(',' || e.dcodes || ',',',' || d.dcode || ',') > 0
  group by e.ename
/

ENAME DNAMES
----- ------------------------------
ept 1 dept 2; dept 3
ept 2 dept 1
ept 3 dept 3; dept 2

SQL>



SY.
...
Рейтинг: 0 / 0
06.09.2021, 14:46
    #40095492
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расшифровка кодов через запятую ("code1, code2" => "Name 1; Name 2")
g_andrew11,

Этот баг был и в 12.2, исправлено в 18/19.


Stax
попробовать lateral (не помню был ли в 12-ке)
да, был, тоже поможет:
Код: 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.
with 
DEPT as (
  select/*+ no_merge */ * from (
   select 'a1' as DCODE, 'dept 1' as DNAME from dual union all
   select 'a2' as DCODE, 'dept 2' as DNAME from dual union all
   select 'a3' as DCODE, 'dept 3' as DNAME from dual
  )
),
EPT as (
  select/*+ no_merge */ * from (
   select 'a2,a3'    as DCODES, 'ept 1' as ENAME from dual union all
   select 'a1' as DCODES, 'ept 2' as ENAME from dual union all
   select 'a3,a2' as DCODES, 'ept 3' as ENAME from dual
  )
)
select e.ENAME,d.DNAMES
  from EPT e
  outer apply 
         (select 
           listagg(dd.DNAME, '; ') within group (order by dd.N) as DNAMES
            from (select d.DNAME, p.LVL as N
                    from (select level as LVL , regexp_substr(e.DCODES, '[^,]+', 1, level) as DCODE
                            from dual
                         connect by regexp_substr(e.DCODES, '[^,]+', 1, level) is not null) p
                    join DEPT d on d.DCODE = p.DCODE
                 ) dd
         ) d;

ENAME DNAMES
----- ------------------------------
ept 1 dept 2; dept 3
ept 2 dept 1
ept 3 dept 3; dept 2
...
Рейтинг: 0 / 0
06.09.2021, 14:55
    #40095498
g_andrew11
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расшифровка кодов через запятую ("code1, code2" => "Name 1; Name 2")
Спасибо всем большое!
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Расшифровка кодов через запятую ("code1, code2" => "Name 1; Name 2") / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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