Извлечение значений из строки в Oracle SQL - PullRequest
1 голос
/ 27 апреля 2019

Я извлекаю возможные значения из поля описания в Oracle. Их тысячи, и я подумал сделать это с помощью SQL.

Вопрос о возможных значениях встраивается в описание после слова «Допустимые значения:» ИЛИ «Допустимое значение:»

Кроме того, значения имеют код и описание, например,

00 = без кода

01 = Дополнительный код

Мне нужно извлечь возможные значения.

Это в таблице Oracle.

Это исходная таблица:

Table1

VAR_NAME    VAR_DESC
Test 1      Code identifying test 1
            Acceptable values:
            00=No code
            01=Additional Code

Test 2      Code identifying test 2
            Acceptable value:
            44=No code

Это выходная таблица:

VAR_NAME    VAR_DESC                    CODE        DESCRIPTION
Test 1      Code identifying test 1     00          No code
            Acceptable values:
            00=No code
            01=Additional Code

Test 1      Code identifying test 1     01          Additional Code
            Acceptable values:
            00=No code
            01=Additional Code


Test 2      Code identifying test 2     44          No code
            Acceptable value:
            44=No code  

Есть ли в Oracle способ извлечь такую ​​информацию?

Ответы [ 2 ]

1 голос
/ 27 апреля 2019

Вы можете использовать regexp_count и regexp_instr вместе. Критическими символами являются = и возврат каретки (chr(10)), как показано ниже:

with table1(var_name,var_desc) as
(
 select 'Test 1',
        'Code identifying test 1
         Acceptable values:
         00=No code
         01=Additional Code' from dual union all
 select 'Test 2',
        'Code identifying test 2
         Acceptable value:
         44=No code'         from dual union all
 select 'Test 3',
        'Code identifying test 3' 
                             from dual       
), table2(var_name,str1,description) as
(
 select var_name,
        case when regexp_count(var_desc,chr(10)) > 0 then
             regexp_substr(var_desc,'[^=]+',regexp_instr(var_desc,chr(10), 1, level))
        end,
        case when regexp_count(var_desc,chr(10)) > 0 then
             regexp_substr(var_desc,'=(.*)+',regexp_instr(var_desc,chr(10), 1, level))
        end 
   from table1
connect by level <= regexp_count(var_desc,chr(10)) 
    and prior var_name = var_name
    and prior sys_guid() is not null   
)    
select t1.*, 
      decode(regexp_count(str1,chr(10)),1,str1) as code, ltrim(str2,'=') as description
 from table2 t2
 join table1 t1 on t1.var_name = t2.var_name
where decode(regexp_count(str1,chr(10)),1,str1) is not null
order by t1.var_name, code;

VAR_NAME    VAR_DESC                 CODE   DESCRIPTION
--------    -----------------------  ----   -----------
Test 1      Code identifying test 1  00     No code
            Acceptable values:
            00=No code
            01=Additional Code

Test 1      Code identifying test 1  01     Additional Code
            Acceptable values:
            00=No code
            01=Additional Code

Test 2      Code identifying test 2  44     No code
            Acceptable value:
            44=No code

Демо

0 голосов
/ 27 апреля 2019

Одним из способов является использование строковых функций.Вот пример подхода с объяснением.

with source_table as (select 
'Code identifying test 1
Acceptable values:
00=No code
01=Additional Code'  val
from dual)
select substr(val, instr(val, chr(10), 1, 2)+1 ,2) code
,substr(val, instr(val, '=', instr(val,chr(10), 1, 2), 1)+1 ,  (  instr(val,chr(10), 1, 3) - instr(val,'=', 1, 1)  ) ) description
from source_table;

Объяснение

Шаг 1. Создание таблицы с данными: вместо того, чтобы фактически создать временную таблицу и добавить тестовые данные, яподделка создания таблицы с использованием предложения WITH .В этом случае я создал таблицу с именем source_table с одним столбцом val .Он содержит одну строку данных, которая является значением в столбце VAR_DESC из строки 1 вашей исходной таблицы.Вам не нужно делать этот бит, поскольку у вас уже есть таблица с данными в вашей базе данных.

with source_table as (select 
'Code identifying test 1
Acceptable values:
00=No code
01=Additional Code'  val
from dual)

Теперь для фактического извлечения строки. INSTR определяет положение подстроки в строке. SUBSTR извлекает подстроку из строки.Итак, я попытался определить шаблон в ваших данных.Первая извлекаемая точка данных следует за вторым символом новой строки (chr (10)) .Получив эту позицию, я извлек из этой точки подстроку длины 2.Следующая извлекаемая подстрока начинается после первого = символа и имеет длину, которая была вычислена как отличие позиции 4-го символа новой строки от первого = символ.

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

Более простой способсделать это - использовать возможности Oracle PL / SQL и создать функцию (которая внутри строки разбивает строку на части), а затем вызвать функцию в SQL.Код можно сделать намного более читабельным.Вы бы использовали те же строковые функции в PL / SQL.Но вы можете сделать это шаг за шагом, чтобы сделать код проще для тех, кому позже понадобится управлять вашим кодом.

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