Oracle SQL - Как вырезать символы из строки с помощью SUBSTR? - PullRequest
0 голосов
/ 23 октября 2018

У меня есть значения типа "ABC1234", "ABC", "DEF456", "GHI" и т. Д. В определенном столбце, который мне нужен.

Теперь мне нужно разбить эту строку, но только если после символа (например, «ABC») следуют цифры.

Так что если значение "ABC1234", то мне нужно вырезать ABC и 1234 отдельно.Но если в качестве значения есть только «ABC», мне просто нужен «ABC».Я не могу найти решение с SUBSTR.Есть ли у вас какие-либо идеи?

Примечание. Длина символов может отличаться от 1 до 10, а также длина от цифр (иногда я не показываю ничего подобного).

Ответы [ 4 ]

0 голосов
/ 23 октября 2018

Попробуйте выполнить приведенный ниже запрос для упомянутых сценариев, я не разделял, если за символами следуют цифры:

with test (col) as
  (select 'ABC1234' from dual union all
   select 'ABC'     from dual union all
   select 'dEfH456'  from dual union all
   select '123GHI'  from dual union all
   select '456'     from dual
  )

  select col,reverse(trim(regexp_replace(reverse(col),'^[0-9]+',' '))) string ,trim(regexp_replace(col,'^[a-zA-Z]+',' ')) numbers from test

, если вы хотите переместить эти символы и строку в любое место, в моем операторе case

with test (col) as
  (select 'ABC1234' from dual union all
   select 'ABC'     from dual union all
   select 'dEfH456'  from dual union all
   select '123GHI'  from dual union all
   select '456'     from dual
  )

  select v.col,case when v.string=v.numbers THEN NULL ELSE string end string , v.numbers
  from (select col,reverse(trim(regexp_replace(reverse(col),'^[0-9]+',' '))) string ,trim(regexp_replace(col,'^[a-zA-Z]+',' ')) numbers from test) v
0 голосов
/ 23 октября 2018

Использование SUBSTRINSTR и TRANSLATE):

SQL Fiddle

Настройка схемы Oracle 11g R2 :

CREATE TABLE data ( value ) AS
SELECT 'ABC1234'     FROM DUAL UNION ALL
SELECT 'ABC123D'     FROM DUAL UNION ALL
SELECT 'ABC '        FROM DUAL UNION ALL
SELECT 'ABC'         FROM DUAL UNION ALL
SELECT 'DEFG456'     FROM DUAL UNION ALL
SELECT 'GHI'         FROM DUAL UNION ALL
SELECT 'JKLMNOPQRS9' FROM DUAL;

Запрос 1 :

SELECT value,
       SUBSTR( value, 1, first_digit - 1 ) AS prefix,
       TO_NUMBER( SUBSTR( value, first_digit ) ) AS suffix
FROM   (
  SELECT value,
         INSTR(
           TRANSLATE( value, '-1234567890', ' ----------' ),
           '-',
           1
         ) AS first_digit
  FROM   data
)
WHERE  SUBSTR( value, first_digit ) IS NOT NULL
AND    TRANSLATE( SUBSTR( value, first_digit ), '-1234567890', ' ' ) IS NULL

Результаты :

|       VALUE |     PREFIX | SUFFIX |
|-------------|------------|--------|
|     ABC1234 |        ABC |   1234 |
|     DEFG456 |       DEFG |    456 |
| JKLMNOPQRS9 | JKLMNOPQRS |      9 |
0 голосов
/ 23 октября 2018

Так что, если значение "ABC1234", то мне нужно вырезать ABC и 1234 отдельно.Но если в качестве значения используется только «ABC», мне просто нужен «ABC».

Среди других решений я предлагаю одно решение, как показано ниже:

Логика :

1) Заменить все цифры на 1.Проверьте положение digit в string.Если в строке нет цифры, используйте String.

2) Извлеките алфавиты из позиции 1st в позицию, где начинается цифра.

3) Извлеките цифру изпозиция начинается до конца.Если цифра не существует, установите ее NULL

  --Dataset Preparation
    with test (col) as
      (select 'ABC1234' from dual union all
       select 'ABC'     from dual union all
       select 'dEfH456'  from dual union all
       select '123GHI'  from dual union all
       select '456'     from dual
      )
     --Query
    select col Original_Column, 
           CASE 
              WHEN (instr(regexp_replace(col,'[0-9]','1'),'1',1)) = 0
           then col
           else
           substr( col,1,instr(regexp_replace(col,'[0-9]','1'),'1',1)-1) 
           end Col_Alp,

           CASE 
              WHEN (instr(regexp_replace(col,'[0-9]','1'),'1',1)) = 0
            then NULL
            Else
            substr( col,instr(regexp_replace(col,'[0-9]','1'),'1',1)) 
            END col_digit    
   from test
   where regexp_like(col, '^[a-zA-Z0-9]+$');

Результат:

SQL> /
Original_Column Col_Alp col_digit
----------      -----   -----
ABC1234      ABC       1234
ABC          ABC       NULL
dEfH456      dEfH      456
123GHI       NULL       123GHI
456          NULL       456
0 голосов
/ 23 октября 2018

Хотелось бы что-нибудь подобное сделать?

SQL> with test (col) as
  2    (select '"ABC1234", "ABC", "dEf456", "123GHI", "456"' from dual),
  3  inter as
  4    (select trim(regexp_substr(replace(col, '"', ''), '[^,]+', 1, level)) token
  5     from test
  6     connect by level <= regexp_count(col, ',') + 1
  7    )
  8  select regexp_substr(token, '^[a-zA-Z]+') letters,
  9         regexp_substr(token, '[0-9]+$') digits
 10  from inter
 11  where regexp_like(token, '^[a-zA-Z]+[0-9]+$');

LETTERS    DIGITS
---------- ----------
ABC        1234
dEf        456

SQL>
...