프로그래밍을 할때처럼 오라클 쿼리에서도 Split을 할수 있는 방법을
찾아보니 대부분 함수로 되어있다. 아래는 간단히 쿼리도 해결할수 있다.
아래 예제는 구분자(|)를 기준으로 'A|B|C|D' 를 Split하는 예제이다.
SELECT distinct regexp_substr(A.TXT, '[^|]+', 1, LEVEL) TXT
FROM (SELECT 'A|B|C|D' TXT FROM dual) A
CONNECT BY LEVEL <= length(regexp_replace(A.TXT, '[^|]+',''))+1
;
--Oracle 8i 이상에서
SELECT substr(A.TXT,
instr(A.TXT, '|', 1, LEVEL) + 1,
instr(A.TXT, '|', 1, LEVEL + 1) - instr(A.TXT, '|', 1, LEVEL) - 1) TXT
FROM (SELECT '|' || 'A|B|C|D' || '|' TXT FROM dual) A
CONNECT BY LEVEL <= length(A.TXT) - length(REPLACE(A.TXT, '|')) - 1
[응용편]
아래는 위의 쿼리를 응용하여 구분자의 컬럼(Column)을 행(Row)으로 바꾸는 쿼리이다.
WITH TEMP_TABLE AS (
SELECT 1 ID, 'A|B|C' TXT FROM DUAL UNION ALL
SELECT 2 ID, 'B|C' TXT FROM DUAL UNION ALL
SELECT 3 ID, 'A|C' TXT FROM DUAL UNION ALL
SELECT 4 ID, 'A|B|C' TXT FROM DUAL UNION ALL
SELECT 5 ID, 'B|C' TXT FROM DUAL UNION ALL
SELECT 6 ID, 'B|C|D' TXT FROM DUAL
)
SELECT A.ID, B.TXT
FROM TEMP_TABLE A
, (
SELECT distinct regexp_substr(AA.TXT, '[^|]+', 1, LEVEL) TXT
FROM (SELECT replace(wm_concat(distinct AAA.TXT),',','|') TXT
FROM TEMP_TABLE AAA) AA
CONNECT BY LEVEL <= length(regexp_replace(AA.TXT, '[^|]+',''))+1
) B
WHERE instr('|' || A.TXT || '|', '|' || B.TXT || '|') > 0
ORDER BY A.ID, B.TXT