마농님..한번만봐주세요 0 4 2,442

by 여비몬 [2013.02.20 13:04:45]



마농님께서 알려주신 쿼리..
부끄럽지만 한번만 더 여쭤볼게요..
어제 설명을 듣고 지금까지 하네요ㅠㅠ
중복되는 천/백/십을 공통적으로 사용할수있게 하려고하는데
이게잘안되네요.. 열심히해보려고하는데 SUBSTR 이 자릿수들땜에 막히네요..
이렇게하는 이유는 시험비슷한거입니다..
같은걸 계속 여쭤봐서 죄송합니다;;
답답한마음에 한번더올리네요..
가르침이 필요합니다ㅜㅜ


ELECT TRANSLATE
    (  SUBSTR(V,  1, 1)||DECODE(SUBSTR(V,  1, 1), 0,'', '천')
    || SUBSTR(V,  2, 1)||DECODE(SUBSTR(V,  2, 1), 0,'', '백')
    || SUBSTR(V,  3, 1)||DECODE(SUBSTR(V,  3, 1), 0,'', '십')
    || SUBSTR(V,  4, 1)||DECODE(SUBSTR(V,  1, 4), 0,'', '조')
    || SUBSTR(V,  5, 1)||DECODE(SUBSTR(V,  5, 1), 0,'', '천')
    || SUBSTR(V,  6, 1)||DECODE(SUBSTR(V,  6, 1), 0,'', '백')
    || SUBSTR(V,  7, 1)||DECODE(SUBSTR(V,  7, 1), 0,'', '십')
    || SUBSTR(V,  8, 1)||DECODE(SUBSTR(V,  5, 4), 0,'', '억')
    || SUBSTR(V,  9, 1)||DECODE(SUBSTR(V,  9, 1), 0,'', '천')
    || SUBSTR(V, 10, 1)||DECODE(SUBSTR(V, 10, 1), 0,'', '백')
    || SUBSTR(V, 11, 1)||DECODE(SUBSTR(V, 11, 1), 0,'', '십')
    || SUBSTR(V, 12, 1)||DECODE(SUBSTR(V,  9, 4), 0,'', '만')
    || SUBSTR(V, 13, 1)||DECODE(SUBSTR(V, 13, 1), 0,'', '천')
    || SUBSTR(V, 14, 1)||DECODE(SUBSTR(V, 14, 1), 0,'', '백')
    || SUBSTR(V, 15, 1)||DECODE(SUBSTR(V, 15, 1), 0,'', '십')
    || SUBSTR(V, 16, 1)
    , '1234567890', '일이삼사오육칠팔구') || '원' V
   FROM (SELECT LPAD(OCRN_AMT, 16, '0') V
   FROM TBCPPA001S01)
by 마농 [2013.02.20 13:14:54]

음.. 제가 저번에 PL/SQL 로 짠거 두번째 버전 올려드렷었는데요.
그건 맘에 안드시나요?
첫번째 버전은 SQL 성격이 강해서
두번째 버전은 절차적으로 풀어드렸었는데요.
두번째 버전이 원하시는 PL/SQL 일듯 합니다만...
그리고 예전 퀴즈낸거 보시면 정규식을 이용한 SQL버전도 있구요.
http://www.gurubee.net/article/58425
질문에 대한 답을 할때 보통 최선의 방법을 찾아 알려드리곤 하는데.
최선의 방법이 아닌걸 요구하실땐 참 난감합니다.
원하시는걸 도와드릴려면 원하시는게 뭔지 정확히 알아야 하는데.
그부분도 명확하지 않구요.
본인이 원하시는것 말고... 이건 지금 불명확합니다.
숙제를 주신분이 내주신 숙제를 토시 하나 틀리지 않고 그대로 옮겨줘 보실래요?


by 여비몬 [2013.02.20 13:22:58]

일단은 제 SQL에문제가 더 있는것같습니다..
그분께서 내주신것은 아시다시피 숫자를 한글로바꾸는것이고
SUBSTR로 쭉 쓴것을보시고 저는 아직 초보이다보니
논리적인걸 가르치려고하십니다..
그래서 어제 그런질문을했던것이었구요
힌트는 주셨지만 마농님과 마찬가지로 4/4/4/4로 나누는것, 조/억만/ 천/백/십 이라는 공통적인 룰
이렇게 알려주셨습니다;
그래서 일단은 SQL문으로 원하는 결과값을 본 후에 PL/SQL문을 해보려고합니다..
죄송해요 이것저것 열심히해봤는데 수준이 딸리네요..

by 마농 [2013.02.20 14:23:41]
WITH t AS
(
SELECT 1 pk, 12345678 amt FROM dual
UNION ALL SELECT 2, 1234567890 amt FROM dual
)
-- 3단계 모두 모아 붙이고, 숫자를 한글로 변환
SELECT pk, amt
     , TRANSLATE(
       XMLAGG(XMLELEMENT(z, x, s) ORDER BY c).Extract('//text()').getStringVal()
       , '1234567890', '일이삼사오육칠팔구'
       ) || '원' v
  FROM (-- 2단계 4개씩 묶어서 조억만 붙이기
        SELECT pk, amt
             , c
             , XMLAGG(XMLELEMENT(z, x, s) ORDER BY lv).Extract('//text()').getStringVal() x
             , SUBSTR('조억만', c, 1) s
          FROM (-- 1단계. 16개로 쪼개 천백십 붙이기
                SELECT pk, amt
                     , lv
                     , SUBSTR(v, lv, 1) x
                     , CEIL(lv / 4) c
                     , SUBSTR('천백십', MOD(lv-1, 4)+1, 1) s
                  FROM (SELECT pk, amt, LPAD(amt, 16, '0') v FROM t)
                     , (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 16)
                 WHERE SUBSTR(v, lv, 1) != '0'
                )
         GROUP BY pk, amt, c
        )
 GROUP BY pk, amt
 ORDER BY pk
;
-- 대량의 Substr 을 사용한 쿼리보다, 이 쿼리가 더 좋아보일수는 있습니다.
-- 그러나 어느정도 내공이 더 쌓인다면 데이터를 쪼갰다가 붙이는
-- 이 과정이 얼마나 부하가 심해질지 알게 될 것입니다.
-- 차라리 투박하더라도 Substr 여러번 사용한게 성능상 더 좋습니다.
-- 그래봤자 자리수가 무한 늘어나는것도 아니고 고작 Substr 32개 썼네요.

by 여비몬 [2013.02.20 14:34:46]

마농님 감사합니다ㅜㅜ
공부열심히할게요
고생하셨습니다..

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입