поиск оракула для значения столбца - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть таблица с данными ниже

create table A 
(id number, 
code varchar2(100));

insert into A values 
(1, '20,21,22'); 
insert into A values 
(2, '22,23,24'); 

commit;

enter image description here

create table code_descriptions
(
code_id number, 
code_desc varchar2(100)); 

insert into code_descriptions values 
(20, 'ABC'); 
insert into code_descriptions values 
(21, 'BBC'); 
insert into code_descriptions values 
(22, 'CAP'); 
insert into code_descriptions values 
(23, 'INC'); 
insert into code_descriptions values 
(24, 'ABC'); 

commit;

enter image description here

Я хотел бы предложить SQL для обновления значений кода таблицы А с описаниями

1,

Не могли бы вы предложить какие-либо функции или идеи для достиженияэто?

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Вы можете маркировать списки через запятую:

select id, level as rn, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1) as code_id
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null;

        ID         RN CODE_ID
---------- ---------- -------
         1          1 20     
         1          2 21     
         1          3 22     
         2          1 22     
         2          2 23     
         2          3 24     

Затем используйте это как CTE (факторинг подзапроса) и присоединитесь к описаниям (я сделал это левым соединением, чтобы вы выбрали, какдля обработки любых пропущенных кодов):

with cte (id, rn, code_id) as (
  select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
  from a
  connect by level <= regexp_count(code, ',') + 1
  and id = prior id
  and prior dbms_random.value is not null
)
select cte.id, cte.rn, cte.code_id, coalesce(cd.code_desc, '??') as code_desc
from cte
left join code_descriptions cd on cd.code_id = cte.code_id;

        ID         RN CODE_ID CODE_DESC
---------- ---------- ------- ---------
         1          1 20      ABC      
         1          2 21      BBC      
         2          1 22      CAP      
         1          3 22      CAP      
         2          2 23      INC      
         2          3 24      ABC      

, а затем объединить их обратно в отдельные значения через запятую:

with cte (id, rn, code_id) as (
  select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
  from a
  connect by level <= regexp_count(code, ',') + 1
  and id = prior id
  and prior dbms_random.value is not null
)
select cte.id,
  listagg(coalesce(cd.code_desc, '??'), ',') within group (order by rn) as code
from cte
left join code_descriptions cd on cd.code_id = cte.code_id
group by cte.id;

        ID CODE            
---------- ----------------
         1 ABC,BBC,CAP     
         2 CAP,INC,ABC     

, а затем объединить или использовать соответствующее обновление:

update a
set code = (
  with cte (id, rn, code_id) as (
    select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
    from a
    connect by level <= regexp_count(code, ',') + 1
    and id = prior id
   and prior dbms_random.value is not null
  ) 
  select listagg(coalesce(cd.code_desc, '??'), ',') within group (order by rn) as code
  from cte
  left join code_descriptions cd on cd.code_id = cte.code_id
  where cte.id = a.id
  group by cte.id
);

2 rows updated.

select * from a;

        ID CODE            
---------- ----------------
         1 ABC,BBC,CAP     
         2 CAP,INC,ABC     

или

rollback; -- just to undo previous update

merge into a
using (
  with cte (id, rn, code_id) as (
    select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
    from a
    connect by level <= regexp_count(code, ',') + 1
    and id = prior id
   and prior dbms_random.value is not null
  ) 
  select cte.id, listagg(coalesce(cd.code_desc, '??'), ',') within group (order by rn) as code
  from cte
  left join code_descriptions cd on cd.code_id = cte.code_id
  group by cte.id
) tmp
on (tmp.id = a.id)
when matched then update set a.code = tmp.code;

2 rows merged.

select * from a;

        ID CODE            
---------- ----------------
         1 ABC,BBC,CAP     
         2 CAP,INC,ABC     

дБ <> скрипка

0 голосов
/ 27 сентября 2019

Самое простое решение - это если число элементов в столбце «код» таблицы А фиксировано - путем непосредственного приклеивания подзапросов к таблице code_description с помощью кодов (мы вырезаем каждый код из строки перечисления).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...