Oracle/SQL2019. 3. 14. 10:15

표준화를 위해 용어를 단어로 분리해보자.


예제를 위해 아래와 같이 테이블을 생성하자.

-- 1
DROP TABLE t_term PURGE;
DROP TABLE t_word PURGE;

CREATE TABLE t_term (term VARCHAR2(100));
CREATE TABLE t_word (word VARCHAR2(100));

INSERT INTO t_term VALUES ('고객번호');
INSERT INTO t_term VALUES ('고객전화번호');
INSERT INTO t_term VALUES ('고객자택전화번호');
INSERT INTO t_term VALUES ('우수고객자택전화번호복문');

INSERT INTO t_word VALUES ('고객');
INSERT INTO t_word VALUES ('전화');
INSERT INTO t_word VALUES ('전화번호');
INSERT INTO t_word VALUES ('번호');

COMMIT;

아래 쿼리로 용어를 단어로 분리할 수 있다. 단어가 길수록 우선순위가 높으며(전화번호 > 전화, 번호), 일치하지 않은 단어는 ?로 표시했다.

-- 2
SELECT   a.term
       , a.term_n
       , a.word
       , NVL2 (REGEXP_REPLACE (a.word, a.word_ag), '?', a.word) AS word_n
    FROM (SELECT a.*
               , b.lv
               , REGEXP_SUBSTR (a.term_n, '[^_]+', 1, b.lv) AS word
            FROM (SELECT a.*
                       , REPLACE (TRIM ('_' FROM REGEXP_REPLACE (a.term, '(' || a.word_ag || ')', '_\1_'))
                                , '__', '_') AS term_n
                    FROM (SELECT  a.term
                                , LISTAGG (a.word, '|') WITHIN GROUP (ORDER BY a.pos) AS word_ag
                             FROM (SELECT a.*
                                        , LAG  (a.word) OVER (PARTITION BY a.term ORDER BY a.pos, a.len) AS word_bf
                                        , LEAD (a.word) OVER (PARTITION BY a.term ORDER BY a.pos, a.len) AS word_af
                                     FROM (SELECT a.term
                                                , b.word
                                                , INSTR (a.term,  b.word) AS pos
                                                , LENGTH (b.word) AS len
                                             FROM t_term a
                                                , t_word b
                                            WHERE INSTR (a.term, b.word) > 0) a) a
                             WHERE NVL (INSTR (a.word_af, a.word), 0) = 0
                               AND NVL (INSTR (a.word_bf, a.word), 0) = 0
                          GROUP BY a.term) a) a
               , (SELECT LEVEL AS lv FROM DUAL CONNECT BY LEVEL <= 10) b
           WHERE b.lv <= REGEXP_COUNT (a.term_n, '_') + 1) a
ORDER BY a.term
       , a.lv;

TERM                     TERM_N                       WORD     WORD_N
------------------------ ---------------------------- -------- --------
고객번호                 고객_번호                    고객     고객
고객번호                 고객_번호                    번호     번호
고객자택전화번호         고객_자택_전화번호           고객     고객
고객자택전화번호         고객_자택_전화번호           자택     ?
고객자택전화번호         고객_자택_전화번호           전화번호 전화번호
고객전화번호             고객_전화번호                고객     고객
고객전화번호             고객_전화번호                전화번호 전화번호
우수고객자택전화번호복문 우수_고객_자택_전화번호_복문 우수     ?
우수고객자택전화번호복문 우수_고객_자택_전화번호_복문 고객     고객
우수고객자택전화번호복문 우수_고객_자택_전화번호_복문 자택     ?
우수고객자택전화번호복문 우수_고객_자택_전화번호_복문 전화번호 전화번호
우수고객자택전화번호복문 우수_고객_자택_전화번호_복문 복문     ?

12 개의 행이 선택되었습니다.


'Oracle > SQL' 카테고리의 다른 글

ORA-00937 에러  (0) 2019.04.22
NVL, NVL2 함수의 인수 평가  (0) 2019.03.29
클로저 테이블 #2  (0) 2019.02.01
클로저 테이블 #1  (0) 2019.01.31
화물수량별 차등운임 계산  (0) 2018.12.27
Posted by 정희락_