Разделить поле Varchar на несколько строк Oracle - PullRequest
0 голосов
/ 27 июня 2018

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

NumberVarchar United

Пример будет следующим.

objectid    linkvalue
    1       1V 2E 3T/B
    2       3C+1E. 3V
    3       5V.4PH
    4       V H
    5       V H 8V

И мне нужно, чтобы вывод был похож на следующий, чтобы вставить его в другую таблицу:

objectid    linkvalue
    1          1V
    1          2E
    1          3T/B
    2          3C
    2          1E
    2          3V
    3          5V
    3          4PH
    4          V H
    5          V H
    5          8V

Есть идеи или предложения, как это сделать? Большое спасибо заранее

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

заменить любые символы разрыва на нормальные (в приведенном ниже примере я использовал пробелы). Затем выполните перекрестное соединение и отфильтруйте все пустые значения.

declare @data table(id int, codes varchar(50))

insert into @data values
(1, '1V 2E 3T/B'),
(2, '3C+1E. 3V'),
(3, '5V4PH')

select id, value
from (select id, replace(replace(replace(codes, 'V', 'V '), '+', ' '), '.', ' ') [codes] 
      from @data) d
cross apply string_split(d.codes, ' ')
where value <> ''
0 голосов
/ 27 июня 2018

Вот еще один способ:

with tbl(objectid, linkvalue) as (
  select 1, '1V 2E 3T/B' from dual union all
  select 2, '3C+1E. 3V' from dual union all
  select 3, '5V.4PH' from dual
)
select objectid,
       regexp_substr(linkvalue, '(.*?)([ +.]+|$)', 1, level, NULL, 1)
from tbl
connect by level <= regexp_count(linkvalue, '[ +.]+') + 1
and prior objectid = objectid
and prior sys_guid() is not null;


OBJECTID    REGEXP_SUBSTR(LINKVALUE,'(.*?)([ +.]+|$)',1,LEVEL,NULL,1)
--------    ----------------------------------------------------------
1           1V
1           2E
1           3T/B
2           3C
2           1E
2           3V
3           5V
3           4PH

Редактировать: добавлен случай, когда нет разделителя. Сделайте пропуск, чтобы добавить пробел между заглавной буквой и цифрой. Конечно, это довольно быстро и грязно, но я не скажу, если вы не будете.

Edit2: допускается для значения, состоящего из нескольких отдельных заглавных букв, разделенных 1 или более разделителями. Однако регулярное выражение становится ужасным.

-- Set up data set
with tbl(objectid, linkvalue) as (
  select 1, '1V 2E 3T/B' from dual union all
  select 2, '3C+1E. 3V' from dual union all
  select 3, '5V.4PH' from dual union all
  select 4, '4H6C' from dual union all
  select 5, 'C E O 8V' from dual union all
  select 6, 'V H' from dual union all
  select 7, '9X X Y Z' from dual
),
-- Add a delimiter where missing
tbl1(objectid, linkvalue) as (
  select objectid,
         regexp_replace(linkvalue, '([A-Z])([0-9])', '\1 \2')
  from tbl
)
select objectid,
       regexp_substr(linkvalue, '(([A-Z][ +.]?)+|.*?)([ +.]+|$)', 1, level, NULL, 1)
from tbl1
connect by regexp_substr(linkvalue, '(([A-Z][ +.]?)+|.*?)([ +.]+|$)', 1, level) is not null
and prior objectid = objectid
and prior sys_guid() is not null;
0 голосов
/ 27 июня 2018

Если разделителями могут быть . или + или , этот запрос работает:

select distinct objectid,regexp_substr(linkvalue,'[^+|.| ]+', 1, level) txt
from (          select 1   objectid,  '1V 2E 3T/B'   linkvalue from dual 
       union all select 2 ,            '3C+1E. 3V'              from dual
       union all select 3,             '5V.4PH'                 from dual)
connect by regexp_substr(linkvalue, '[^+|.| ]+', 1, level) is not null
order by 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...