2013-02-05 2 views
0

큰 텍스트 블록 인 메모 필드를 가져 오려고하는데 샘플 데이터는 마치 테이블에 삽입하는 것처럼 아래에 있습니다.sql regex는 새 줄에 추가 할 텍스트를 구문 분석합니다.

create table test_table 
(
job_number number, 
notes varchar2(4000) 
) 

insert into test_table (job_number,notes) 
values (12345,1022089483 notes notes notes notes 1022094450 notes notes notes notes 1022095218 notes notes notes notes) 

나는 각 노트 항목 (노트를 선도하는 10 개 자리 숫자는 유닉스 타임 스탬프입니다)에 대한 별도의 레코드가 있으므로 그것을 구문 분석 할 필요가있다. 내가 파이프에 수출한다면 그래서 같을 것이다 구분 :

job_number | 노트

12345 1022089483 노트 노트 | | 1,022,094,450 노트는 노트

노트

12345 노트 12345 | 1022095218 메모 메모 메모 메모

정말이 말이 맞는 것이 좋습니다. 나는 어떤 통찰력을 주셔서 감사합니다. 이 일을

+0

행당 메모 수가 다를 것이라고 생각하십니까? 또한 오라클 버전은 무엇입니까? – DazzaL

+0

예, 노트 수는 다양합니다. 우리는 8 또는 9에 있다고 생각합니다. regex는 내장되어 있지 않지만 정규 표현식을 수행하는 함수를 만들었습니다. – user1588433

답변

0

몇 가지 방법 :

SQL> insert into test_table (job_number,notes) 
    2 values (12345,'1022089483 notes notes notes notes 1022094450 notes notes notes notes 1022095218 notes notes notes notes'); 

1 row created. 

SQL> insert into test_table (job_number,notes) 
    2 values (12346,'1022089483 notes notes notes notes 1022094450 foo 1022095218 test notes 1022493228 the answer is 42'); 

1 row created. 

SQL> commit; 

Commit complete. 

참고 : 내가 [0-9]{10}을 사용하고 메모를 결정하기 위해 내 정규식으로 (즉, 모든 10 자리 번호를 메모의 시작으로 간주됩니다).

처음으로, 주어진 행에서 최대 메모 수를 계산 한 다음 그 수의 행으로 데카르트 조인을 수행 할 수 있습니다. 음의 수는 일반적으로 (우리는 재귀 조회를 많이하고있는 것처럼 차이가 더 큰 악화이, 확장)와 동일하다만큼 괜찮

SQL> with data 
    2 as (select job_number, notes, 
    3   (length(notes)-length(regexp_replace(notes, '[0-9]{10}', null)))/10 num_of_notes 
    4  from test_table t) 
    5 select job_number, 
    6   substr(d.notes, regexp_instr(d.notes, '[0-9]{10}', 1, rn.l), 
    7      regexp_instr(d.notes||' 0000000000', '[0-9]{10}', 1, rn.l+1) 
    8      -regexp_instr(d.notes, '[0-9]{10}', 1, rn.l) -1 
    9    ) note 
10 from data d 
11   cross join (select rownum l 
12      from dual 
13     connect by level <= (select max(num_of_notes) 
14           from data)) rn 
15 where rn.l <= d.num_of_notes 
16 order by job_number, rn.l; 

JOB_NUMBER NOTE 
---------- -------------------------------------------------- 
    12345 1022089483 notes notes notes notes 
    12345 1022094450 notes notes notes notes 
    12345 1022095218 notes notes notes notes 
    12346 1022089483 notes notes notes notes 
    12346 1022094450 foo 
    12346 1022095218 test notes 
    12346 1022493228 the answer is 42 

7 rows selected. 

: 다음 각 음을 필터링 할 수 있습니다.

우리는 위와 같은 일을 할 수있는 resursive 인수 분해 된 하위 쿼리를 사용할 수 있지만 추가 루프하지 않는 11g의

:

SQL> with data (job_number, notes, note, num_of_notes, iter) 
    2 as (select job_number, notes, 
    3    substr(notes, regexp_instr(notes, '[0-9]{10}', 1, 1), 
    4     regexp_instr(notes||' 0000000000', '[0-9]{10}', 1, 2) 
    5     -regexp_instr(notes, '[0-9]{10}', 1, 1) -1 
    6     ), 
    7    (length(notes)-length(regexp_replace(notes, '[0-9]{10}', null)))/10 num_of_notes, 
    8    1 
    9  from test_table 
10  union all 
11  select job_number, notes, 
12    substr(notes, regexp_instr(notes, '[0-9]{10}', 1, iter+1), 
13     regexp_instr(notes||' 0000000000', '[0-9]{10}', 1, iter+2) 
14     -regexp_instr(notes, '[0-9]{10}', 1, iter+1) -1 
15     ), 
16    num_of_notes, iter + 1 
17  from data 
18  where substr(notes, regexp_instr(notes, '[0-9]{10}', 1, iter+1), 
19     regexp_instr(notes||' 0000000000', '[0-9]{10}', 1, iter+2) 
20     -regexp_instr(notes, '[0-9]{10}', 1, iter+1) -1 
21     ) is not null 
22 ) 
23 select job_number, note 
24 from data 
25 order by job_number, iter; 

JOB_NUMBER NOTE 
---------- -------------------------------------------------- 
    12345 1022089483 notes notes notes notes 
    12345 1022094450 notes notes notes notes 
    12345 1022095218 notes notes notes notes 
    12346 1022089483 notes notes notes notes 
    12346 1022094450 foo 
    12346 1022095218 test notes 
    12346 1022493228 the answer is 42 

7 rows selected. 

또는 10g에서 이후 우리가 확인하기 위해 모델 절을 사용할 수를 행 :

SQL> with data as (select job_number, notes, 
    2      (length(notes)-length(regexp_replace(notes, '[0-9]{10}', null)))/10 num_of_notes 
    3     from test_table) 
    4 select job_number, note 
    5 from data 
    6 model 
    7 partition by (job_number) 
    8 dimension by (1 as i) 
    9 measures (notes, num_of_notes, cast(null as varchar2(4000)) note) 
10 rules 
11 (
12 note[for i from 1 to num_of_notes[1] increment 1] 
13  = substr(notes[1], 
14    regexp_instr(notes[1], '[0-9]{10}', 1, cv(i)), 
15    regexp_instr(notes[1]||' 0000000000', '[0-9]{10}', 1, cv(i)+1) 
16    -regexp_instr(notes[1], '[0-9]{10}', 1, cv(i)) -1 
17    ) 
18 ) 
19 order by job_number, i; 

JOB_NUMBER NOTE 
---------- -------------------------------------------------- 
    12345 1022089483 notes notes notes notes 
    12345 1022094450 notes notes notes notes 
    12345 1022095218 notes notes notes notes 
    12346 1022089483 notes notes notes notes 
    12346 1022094450 foo 
    12346 1022095218 test notes 
    12346 1022493228 the answer is 42 
+0

도움을 주셔서 대단히 감사드립니다. – user1588433

관련 문제