DATOR


한 컬럼내의 구분자로 연결된 문자열을 종으로(로우로) 분리하는 쿼리_정규표현식 활용 (2/3) Oracle


지난번에 올린 "한 컬럼내의 구분자로 연결된 문자열을 종으로(로우로) 분리하는 쿼리"는 문자열을 추출하는 로직에 대하여
좀더 간단하게 해결할 수 있는 방안을 여러분들이 조언해 주셔서 해당 쿼리를 올립니다.

아래 쿼리는 정규표현식을 이용하여 데이터를 추출하는 방식입니다.
쿼리가 훨씬 단순해지고 보기편해졌네요. 
다만, 정규표현식은 오라클 버전을 타기 때문에 사용 시 오라클 버전을 확인해야 합니다.


=> COPY_T 테이블을 활용하여 구분자 개수만큼 데이터 증가

WITH AA AS 
(SELECT 1 NUM, 'A1|B1' NAME FROM DUAL UNION ALL 
 SELECT 2,  'A2|B2|C2'  FROM DUAL UNION ALL 
 SELECT 3, 'A3|B3|C3|D3' FROM DUAL)
, BB AS 
(SELECT AA.*, LENGTH(NAME) - LENGTH(REPLACE(NAME,'|','')) + 1 WORD_CNT FROM AA)
SELECT REGEXP_SUBSTR(NAME,'[^|]+',1,NO) WORD, NO, NUM
  FROM BB INNER JOIN COPY_T T ON T.NO <= BB.WORD_CNT
 ORDER BY NUM, WORD, NO
;

=> CONNECT BY을 활용하여 구분자 개수만큼 데이터 증가
SELECT NUM
     , LTRIM(REGEXP_SUBSTR('|'||NAME, '\|[^\|]+', DECODE(NO, 1, 1, INSTR(NAME, '|', 1, NO-1))), '|') as NAME
FROM
      (SELECT 1 NUM, 'A1|B1' NAME       FROM DUAL UNION ALL
       SELECT 2 NUM, 'A2|B2|C2' NAME    FROM DUAL UNION ALL
       SELECT 3 NUM, 'A3|B3|C3|D3' NAME FROM DUAL) A,
      (SELECT LEVEL NO FROM DUAL CONNECT BY LEVEL <= 10) B  -- 구분자로 연결한 단어가 최대 10을 넘지 않는다고 전제.
WHERE  NO <= REGEXP_COUNT(A.NAME, '\|', 1, 'i') + 1
ORDER BY NUM, NAME;

TAG

Leave Comments