Как разделить имя, разделенное запятой (даже вхождение) в оракуле? - PullRequest
0 голосов
/ 20 марта 2019
select EL_VALUES_FIELD1, regexp_substr(f_person_name_multiple(EL_VALUES_FIELD2,0), '[^,  ]+', 1, level)
from DATA_FORM_VALUES_1322308
connect BY  regexp_substr(f_person_name_multiple(EL_VALUES_FIELD2,0),'[^,  ]+', 1, level) is not null

Строка ввода выглядит следующим образом:

Kanodia, Gaurav,Punani, Rohit,Singhal, Bhavya

Ожидаемый результат выглядит следующим образом

Kanodia, Gaurav
Punani, Rohit
Singhal, Bhavya

Ответы [ 3 ]

3 голосов
/ 20 марта 2019

Если входная строка всегда выглядит так, как вы нам показали, то

  • замените вторую запятую чем-то другим (например, #)
  • разбить входную строку на # (вместо ,)
  • level в этом случае всегда будет <= 2

SQL> with test (col) as (select 'Kanodia, Gaurav,Punani, Rohit' from dual)
  2  select regexp_substr(regexp_replace(col, ',', '#', 1, 2), '[^#]+', 1, level) res
  3  from test
  4  connect by level <= 2;

RES
-----------------------------
Kanodia, Gaurav
Punani, Rohit

SQL>

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


[EDIT ]

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

SQL> create or replace function f_rep (par_string in varchar2)
  2    return varchar2
  3  is
  4    -- replace every second occurrence of a comma with a #
  5    l_cnt  number := regexp_count(par_string, ',');
  6    l_str  varchar2(100) := par_string;
  7  begin
  8    for i in 1 .. l_cnt loop
  9      if mod(i, 2) = 0 then
 10         l_str := regexp_replace(l_str, ',', '#', 1, (i/2)+1);
 11      end if;
 12    end loop;
 13    return l_str;
 14  end;
 15  /

Function created.

SQL>

Этот запрос показывает, как избежать неправильного результата при наличии нескольких строк.

SQL> with test (col) as
  2    (select 'Kanodia, Gaurav,Punani, Rohit,Singhal, Bhavya'            from dual union all
  3     select 'Little, Foot, MT0, DbFiddle'                              from dual union all
  4     select 'January, February, March, April, May, June, July, August' from dual)
  5  select
  6    col,
  7    trim(regexp_substr(f_rep(col), '[^#]+', 1, column_value)) repcol_split
  8  from test,
  9       table(cast(multiset(select level from dual
 10                           connect by level <= regexp_count(f_rep(col), '#') + 1
 11                          ) as sys.odcinumberlist));

COL                                                      REPCOL_SPLIT
-------------------------------------------------------- --------------------
Kanodia, Gaurav,Punani, Rohit,Singhal, Bhavya            Kanodia, Gaurav
Kanodia, Gaurav,Punani, Rohit,Singhal, Bhavya            Punani, Rohit
Kanodia, Gaurav,Punani, Rohit,Singhal, Bhavya            Singhal, Bhavya
Little, Foot, MT0, DbFiddle                              Little, Foot
Little, Foot, MT0, DbFiddle                              MT0, DbFiddle
January, February, March, April, May, June, July, August January, February
January, February, March, April, May, June, July, August March, April
January, February, March, April, May, June, July, August May, June
January, February, March, April, May, June, July, August July, August

9 rows selected.

SQL>
0 голосов
/ 20 марта 2019

Это не использует регулярные выражения (только простые строковые функции) и будет работать для нескольких строк ввода:

Установка Oracle :

CREATE TABLE test_data ( id, col ) AS
SELECT 1, 'Kanodia, Gaurav,Punani, Rohit,Singhal, Bhavya' FROM DUAL UNION ALL
SELECT 2, 'Alice, Apple,Barry, Banana,Claire, Cherry' FROM DUAL

Запрос

WITH rsqfc ( id, col, string_start, string_end ) AS (
  SELECT id,
         col,
         1,
         INSTR( col, ',', 1, 2 )
  FROM   test_data
UNION ALL
  SELECT id,
         col,
         string_end + 1,
         INSTR( col, ',', string_end + 1, 2 )
  FROM   rsqfc
  WHERE  string_end > 0
)
SELECT id,
       CASE string_end
       WHEN 0
       THEN SUBSTR( col, string_start )
       ELSE SUBSTR( col, string_start, string_end - string_start )
       END  AS pair
FROM   rsqfc;

выход

ID | PAIR           
-: | :--------------
 1 | Kanodia, Gaurav
 2 | Alice, Apple   
 1 | Punani, Rohit  
 2 | Barry, Banana  
 1 | Singhal, Bhavya
 2 | Claire, Cherry 

дБ <> скрипка здесь

0 голосов
/ 20 марта 2019
-- for one row
with s as
(select 'Kanodia, Gaurav,Punani, Rohit' str from dual)
select regexp_substr(str, '[^,]+,[^,]+', 1, level) str
from s
connect by level <= ceil(regexp_count(str, ',') / 2);

STR
------------------------------
Kanodia, Gaurav
Punani, Rohit

Elapsed: 00:00:00.00

-- for multiple rows
with s as
(select 1 id, 'Kanodia, Gaurav,Punani, Rohit' str from dual union all
 select 2 id, '1, 2, 3, 4' str from dual union all
 select 3 id, '6, 7, 8, 9' str from dual
)
select id, level num, regexp_substr(str, '[^,]+,[^,]+', 1, level) str
from s
connect by id = prior id and level <= ceil(regexp_count(str, ',') / 2)
and prior dbms_random.value is not null;

        ID        NUM STR
---------- ---------- ------------------------------
         1          1 Kanodia, Gaurav
         1          2 Punani, Rohit
         2          1 1, 2
         2          2  3, 4
         3          1 6, 7
         3          2  8, 9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...