숫자와 문자, 특수문자 조합의 컬럼에서 그냥 숫자만도 아닌 특정 숫자의 특정 자릿수 만큼만 추출하는 쿼리문 관련해서 질문드립니다. 0 6 5,380

by NExT맨 [SQL Query] PL/SQL ORACLE SQL QUERY INSTR REPLACE LENGTH SUBSTR [2012.12.28 10:59:50]


한 컬럼에 아래와 같이 무수히 많은 문자와 숫자, 공백, 특수문자 등이 규칙 없이 나열되어 있습니다.

=========================================== 1 행 ===========================================

##VVVIPP_NO:=0947582923984           ##ABCDEF_CD:=SUMIN_B01##NBACVP_NM:=이거 너무 어려워요##APPLE_DT:=20121203        ##APPLY_TM:=155126      ##APPLY_WAY:=##REC_GB:=002006##NAME:=홍길동##ACPT_MINs:=7707171171717##ACPT_NM:=장혁##EXPECTED_DT:=20121205        ##EXPECTED_TM:=155100      ##TREAT_GAMES_ID:=0505050505053##TREAT_TEAM:=프랑스##DUE_DATE:=20121205        155100



=========================================== 2 행 ===========================================

##VVVIPP_NO:=0947582923984           ##ABCDEF_CD:=SUMIN_B04##SKYRIM_NM:=여러분 사랑합니다.##APPLE_DT:=20121203        ##APPLY_TM:=154056      ##APPLY_WAY:=##REC_GB:=002009##NAME:=임꺽정##ACPT_MINs:=8808181181818##ACPT_NM:=고소영##EXPECTED_DT:=20121204        ##EXPECTED_TM:=094100      ##TREAT_GAMES_ID:=8809271161543##TREAT_TEAM:=이탈리아##DUE_DATE:=20121204        094100



=========================================== 3 행 ===========================================

##VVVIPP_NO:=0947582923984           ##ABCDEF_CD:=SUMIN_B14##MGTANB_NM:=가나다라마바사흐어엉엉##APPLE_DT:=20121203        ##APPLY_TM:=154402      ##APPLY_WAY:=##REC_GB:=002002##NAME:=장길산##ACPT_MINs:=6903282178654##ACPT_NM:=아이유##EXPECTED_DT:=20121205        ##EXPECTED_TM:=180000      ##TREAT_GAMES_ID:=0374639374654##TREAT_TEAM:=아일랜드##DUE_DATE:=20121205        180000



=========================================== 3 행 ===========================================

##MW_AFR_NM:=새해 복 많이 받으세요##MW_NOTES:=##DEAL_GBN:=01  ##DEAL_DTL:=##DEAL_BAS:=크하하-13687(2012.12.03.)유재석이 최고의 MC(상상플러스)##XCVBTYUN_DTTGHT:=##MW_TRANS_MET_CODE:=##CANCEL_CHECK:=##DPP_USR_ID:=9008142156784



=========================================== 4 행 ===========================================

##MC_AFR_NM:=새해 복 많이 받으세요##MC_NOTES:=##MC_ABCD_STATUS:=30  ##TAKE_CONFRM_DTHR:=20121203162836              ##TAKE_CONFRM_CODE:=Y ##TAKE_CONFRM_USR_ID:=9008142156784             ##APPLE_JOBS_REG_CONFRM:=N ##MC_PPS_GET_ID:=8809271161543            ##DPP_USR_ID:=SSSV_8809271161543                   ##DEAL_DDDD_MAN_USR_:=0946353823455



=========================================== 5 행 =========================================== 

##MV_AFR_NM:=새해 복 많이 받으세요##MW_NOTES:=가나다라마바사아자차카타파하##DEAL_GBN:=01  ##DEAL_DTL:=##DEAL_BAS:=가나다라마바사아자차카타파하##CXRTSVP_CRROPP:=##MV_TRANS_MET_CODE:=##CANCEL_CHEKK:=##DPP_USR_ID:=2011271165437



=========================================== 6 행 =========================================== 
##MV_AFR_NM:=메리 크리스마스입니다.##MW_NOTES:=무한도전무한도전##MV_CCRP_STATUS:=30  ##TAKE_CONFRM_DTHR:=20121203164621              ##TAKE_CONFRM_CODE:=Y ##TAKE_CONFRM_USR_ID:=2011271165437             ##APPLC_DEP_REG_CONFRM:=N ##MV_PPS_GET_USR_ID:=2011271165437             ##DPP_USER_IDVC:=9952345345620                 ##DEAL_DXDY_MAN_USR_ID:=9907242116654 

............................

이중 인덱스된 주민등록번호(가짜임)만 따로 추출하는 쿼리를 만들고 싶습니다.
위는 극히 일부만 추출한 것일 뿐 실제로는 수십만건이나 됩니다.

고수님들의 답변 부탁드리며 가능한지 여부만이라도 확인해주셨으면 감사하게스므니다. ,',

(참고로 토드에 오라클 10g 쓰고 있어요..)
by 마농 [2012.12.28 12:46:31]
WITH t AS
(
SELECT 1 pk, '##VVVIPP_NO:=0947582923984      ##ABCDEF_CD:=SUMIN_B01##MINWON_NM:=이거 너무 어려워요##APPLE_DT:=20121203    ##APPLY_TM:=155126   ##APPLY_WAY:=##REC_GB:=002006##NAME:=홍길동##ACPT_MINs:=7707171171717##ACPT_NM:=장혁##EXPECTED_DT:=20121205    ##EXPECTED_TM:=155100   ##TREAT_GAMES_ID:=0505050505053##TREAT_TEAM:=프랑스##DUE_DATE:=20121205    155100' str FROM dual
UNION ALL SELECT 2, '##VVVIPP_NO:=0947582923984      ##ABCDEF_CD:=SUMIN_B04##MINWON_NM:=여러분 사랑합니다.##APPLE_DT:=20121203    ##APPLY_TM:=154056   ##APPLY_WAY:=##REC_GB:=002009##NAME:=임꺽정##ACPT_MINs:=8808181181818##ACPT_NM:=고소영##EXPECTED_DT:=20121204    ##EXPECTED_TM:=094100   ##TREAT_GAMES_ID:=8809271161543##TREAT_TEAM:=이탈리아##DUE_DATE:=20121204    094100' FROM dual
UNION ALL SELECT 3, '##VVVIPP_NO:=0947582923984      ##ABCDEF_CD:=SUMIN_B14##MINWON_NM:=가나다라마바사흐어엉엉##APPLE_DT:=20121203    ##APPLY_TM:=154402   ##APPLY_WAY:=##REC_GB:=002002##NAME:=장길산##ACPT_MINs:=6903282178654##ACPT_NM:=아이유##EXPECTED_DT:=20121205    ##EXPECTED_TM:=180000   ##TREAT_GAMES_ID:=0374639374654##TREAT_TEAM:=아일랜드##DUE_DATE:=20121205    180000' FROM dual
UNION ALL SELECT 4, '##MW_AFR_NM:=새해 복 많이 받으세요##MW_NOTES:=##DEAL_GBN:=01 ##DEAL_DTL:=##DEAL_BAS:=크하하-13687(2012.12.03.)유재석이 최고의 MC(상상플러스)##XCVBTYUN_DTTGHT:=##MW_TRANS_MET_CODE:=##CANCEL_CHECK:=##DPP_USR_ID:=9008142156784' FROM dual
UNION ALL SELECT 5, '##MW_AFR_NM:=새해 복 많이 받으세요##MW_NOTES:=##MW_ABCD_STATUS:=30 ##TAKE_CONFRM_DTHR:=20121203162836       ##TAKE_CONFRM_CODE:=Y ##TAKE_CONFRM_USR_ID:=9008142156784       ##APPLE_JOBS_REG_CONFRM:=N ##MW_PPS_GET_ID:=8809271161543      ##DPP_USR_ID:=SSSV_8809271161543          ##DEAL_DDDD_MAN_USR_:=0946353823455' FROM dual
UNION ALL SELECT 6, '##MW_AFR_NM:=새해 복 많이 받으세요##MW_NOTES:=가나다라마바사아자차카타파하##DEAL_GBN:=01 ##DEAL_DTL:=##DEAL_BAS:=가나다라마바사아자차카타파하##CXRTSVP_CRROPP:=##MW_TRANS_MET_CODE:=##CANCEL_CHEKK:=##DPP_USR_ID:=2011271165437' FROM dual
UNION ALL SELECT 7, '##MW_AFR_NM:=메리 크리스마스입니다.##MW_NOTES:=무한도전무한도전##MW_CCRP_STATUS:=30 ##TAKE_CONFRM_DTHR:=20121203164621       ##TAKE_CONFRM_CODE:=Y ##TAKE_CONFRM_USR_ID:=2011271165437       ##APPLC_DEP_REG_CONFRM:=N ##MW_PPS_GET_USR_ID:=2011271165437       ##DPP_USER_IDVC:=9952345345620         ##DEAL_DXDY_MAN_USR_ID:=9907242116654 ' FROM dual
)
SELECT pk
     , TRIM(REGEXP_SUBSTR(str, ' [0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 1)) v1
     , TRIM(REGEXP_SUBSTR(str, ' [0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 2)) v2
     , TRIM(REGEXP_SUBSTR(str, ' [0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 3)) v3
     , TRIM(REGEXP_SUBSTR(str, ' [0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 4)) v4
     , TRIM(REGEXP_SUBSTR(str, ' [0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 5)) v5
  FROM (SELECT pk, ' '||REGEXP_REPLACE(str, '[^0-9]', ' ')||' ' str FROM t)
;

by 손님 [2012.12.28 15:01:40]
마농님 감사합니다. 새해 복 많이 받으세요^^

by NExT맨 [2012.12.28 15:03:58]
마농님 우선 감사합니다.  

근데 혹시 스트링을 일일이 집어넣지 않고 번호를 추출할 수 있는 방법이 있을까요?

by 마농 [2012.12.28 15:41:20]

With 문은 참고용, 테스트용입니다. 쿼리만 보세요.


by NExT맨 [2012.12.28 17:44:49]
 흐흐 해결했습니다. 

마농님이 알려주신 방법이랑은 약간 다른데 아래 처럼 했습니다. 참고로 한 행에 여러 주민번호가 있는건
답이 안나오네요. ㅜㅜ

암튼 마농님 다시 한번 감사드립니다.

SELECT * FROM
(SELECT 
DECODE(INSTR(A.컬럼명,' '),A.컬럼명,SUBSTR(A.컬럼명,0,INSTR(A.컬럼명,' ',13,1)-1) 
|| INSTR(A.컬럼명,'#'),'0',A.컬럼명,SUBSTR(A.컬럼명,0,INSTR(A.컬럼명,'#',13,1)-1)) AS 컬럼명1
FROM (SELECT SUBSTR(컬럼명,INSTR(컬럼명,'ID:=',13,1)+4) 컬럼명 FROM 테이블명) A 
)AA
WHERE 1 = 1 
AND   REGEXP_LIKE(컬럼명,'^[5-8]')  
AND   NOT REGEXP_LIKE(컬럼명, '[a-z]|[A-Z]')
AND   NOT REGEXP_LIKE(컬럼명, '[@/.;*^,★☆#!]|[?]|[-]|[ㄱ-ㅎ]|[ㅏ-ㅣ]' )
AND   NOT REGEXP_LIKE(컬럼명,'[가-황]')
AND   NOT REGEXP_LIKE(컬럼명, '[가-힛].*');

================================================================================
SELECT REGEXP_instr(CUST_NM,'[a-z]|[A-Z]'), a.*                                            -- 영문자 위치 반환
FROM   customer.tza011 a
WHERE  1 = 1
  AND  REGEXP_LIKE(CUST_NM, '[^[:digit:]]')                                                    -- 첫글자가  문자
  AND  NOT REGEXP_LIKE(CUST_NM,'[a-z]|[A-Z]')                                             -- 영문자 제외
  AND  NOT REGEXP_LIKE(CUST_NM,'[0-9]|[@/.;*^,★☆#!]|[?]|[-]|[ㄱ-ㅎ]|[ㅏ-ㅣ]')   -- 특수문자제회
  AND  REGEXP_LIKE(CUST_NM, '.*가.*|.*나.*|.*다.*');                                        -- 가 나다 포함
  AND  NOT REGEXP_LIKE(CUST_NM,'[가-황]')                                                  -- 한글제외1
  AND  NOT REGEXP_LIKE(CUST_NM, '[가-힛].*' )                                              -- 한글제외2
  AND  NOT REGEXP_LIKE(CUST_NM, '[A-Z]|[?@/.히]' )                                   --특수문자 제외
  AND  NOT REGEXP_LIKE(CUST_NM,'[ㄱ-ㅎ]')                                                  -- 자음 포함된 관측치 제외
  AND  NOT REGEXP_LIKE(CUST_NM,'^[a-z]|[A-Z]');                                       -- 첫글자가 영문자인경우 제외

by 마농 [2012.12.28 18:27:01]
-- REGEXP_LIKE(컬럼명,'^[5-8]') 이부분으로 보아서는 1950년대생부터 1980년대생까지 뽑는 거네요.
-- 제가 알려드린 방식의 맨앞 두자리 체크하는 것을 조금만 바꾸시면 됩니다.
-- 저는 출생년도를 00~99 까지 뽑았는데... [0-9]{2}
-- 출생년도를 50~89까지 뽑는걸로 바꾸면... [5~8][0-9]
SELECT TRIM(REGEXP_SUBSTR(str, ' [5~8][0-9](0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 1)) v1 
     , TRIM(REGEXP_SUBSTR(str, ' [5~8][0-9](0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 2)) v2 
     , TRIM(REGEXP_SUBSTR(str, ' [5~8][0-9](0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 3)) v3 
     , TRIM(REGEXP_SUBSTR(str, ' [5~8][0-9](0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 4)) v4 
     , TRIM(REGEXP_SUBSTR(str, ' [5~8][0-9](0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|30|31)[0-9]{7} ', 1, 5)) v5 
  FROM (SELECT ' '||REGEXP_REPLACE(cust_nm, '[^0-9]', ' ')||' ' str FROM customer.tza011)
;
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입