Пользовательская функция, которая условно разбивает текст на столбцы Oracle - PullRequest
0 голосов
/ 05 августа 2020

Я новичок в Oracle Базах данных или Базах данных в целом, и я сталкиваюсь со случаем, который быстро превращается в серьезную головную боль

У меня есть запрос, который группирует и возвращает идентификаторы адресов для заданного client и каждый идентификатор адреса имеют связанный тип, который мне нужен в отдельных столбцах

Запрос, который у меня сейчас есть, возвращает примерно следующее:

   CLIENT_ID    ADDRESS_AGG_TYP
   12345        6882|HOME;8273|WORK;3192|OTHER
   52345        5523|OTHER;1345|HOME;9547|WORK
   74563        4431|OTHER;6456|WORK;7567|HOME
   34534        1543|WORK;5634|HOME;5123|OTHER

ADDRESS_AGG_TYP - это LISTAGG, сгруппированный по идентификатору клиента поверх concat address_id и типа из адресов

ddl таблицы, вероятно, выглядит примерно так.

CREATE TABLE addresses
( address_id number(*) primary key,
  client_id number(*),
  type varchar2(70),
  address_line_1 varchar2(70),
  address_line_2 varchar2(70)
);

Мне нужно преобразовать вывод примерно в это:

   CLIENT_ID    HOME     WORK     OTHER
   12345        6882     8273     3192
   52345        1345     9547     5523
   74563        7567     6456     4431
   34534        5634     1543     5123

Есть идеи, как я могу это сделать? Я предполагаю, что для этого может потребоваться определенная пользователем функция, но я не могу осмыслить это.

Это на Oracle DB Version 12 C

1 Ответ

0 голосов
/ 05 августа 2020

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

Сначала я добавляю ';' до начала строки, как показано в блоке данных.

Я определяю регулярное выражение как шаблон, который начинается с; за которыми следуют числа и заканчиваются на \ HOME, \ WORK или \ OTHER.

Затем из извлеченной части я делаю ее дальше, чтобы получить только числа

with data
 as (
   select 12345 as client_id,';'||'6882|HOME;8273|WORK;3192|OTHER' as address_agg_typ from dual union all
   select 52345 as client_id,';'||'5523|OTHER;1345|HOME;9547|WORK' as address_agg_typ from dual union all
   select 74563 as client_id,';'||'4431|OTHER;6456|WORK;7567|HOME' as address_agg_typ from dual union all
   select 34534 as client_id,';'||'1543|WORK;5634|HOME;5123|OTHER' as address_agg_typ from dual 
    )
select client_id
      ,substr(
              regexp_substr(address_agg_typ,';[0-9]*\|HOME')
              ,2
              ,instr(regexp_substr(address_agg_typ,';[0-9]*\|HOME'),'HOME')
               -3
              ) as home_extract
      ,substr(
              regexp_substr(address_agg_typ,';[0-9]*\|WORK')
              ,2
              ,instr(regexp_substr(address_agg_typ,';[0-9]*\|WORK'),'WORK')
               -3
              ) as work_extract              
      ,substr(
              regexp_substr(address_agg_typ,';[0-9]*\|OTHER')
              ,2
              ,instr(regexp_substr(address_agg_typ,';[0-9]*\|OTHER'),'OTHER')
               -3
              ) as other_extract                            
  from data


+-----------+--------------+--------------+---------------+
| CLIENT_ID | HOME_EXTRACT | WORK_EXTRACT | OTHER_EXTRACT |
+-----------+--------------+--------------+---------------+
|     12345 |         6882 |         8273 |          3192 |
|     52345 |         1345 |         9547 |          5523 |
|     74563 |         7567 |         6456 |          4431 |
|     34534 |         5634 |         1543 |          5123 |
+-----------+--------------+--------------+---------------+

ссылка на скрипт db

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=41a7a4fb3286326b1cb0baf1512aca1b

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