[답변] 코드테이블과의 Cartesian product 이용 0 3 2,855

by 마농 Cartesian product [2008.09.01 16:42:41]


 

WITH elec_code AS
(
SELECT 1 no, '000' elec_cd FROM dual
UNION ALL SELECT  2, '110' FROM dual
UNION ALL SELECT  3, '140' FROM dual
UNION ALL SELECT  4, '170' FROM dual
UNION ALL SELECT  5, '185' FROM dual
UNION ALL SELECT  6, '200' FROM dual
UNION ALL SELECT  7, '237' FROM dual
UNION ALL SELECT  8, '245' FROM dual
UNION ALL SELECT  9, '255' FROM dual
UNION ALL SELECT 10, '265' FROM dual
UNION ALL SELECT 11, '275' FROM dual
)
SELECT DECODE(rn,1,card_bank_code)  "카드사"
     , DECODE(rn,1,'A',3,'B',5,'C') "구분1"
     , DECODE(MOD(rn,2),1,'건수',0,'금액') "구분2"
     , MIN(DECODE(no, 1,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "000"
     , MIN(DECODE(no, 2,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "110"
     , MIN(DECODE(no, 3,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "140"
     , MIN(DECODE(no, 4,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "170"
     , MIN(DECODE(no, 5,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "185"
     , MIN(DECODE(no, 6,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "200"
     , MIN(DECODE(no, 7,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "237"
     , MIN(DECODE(no, 8,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "245"
     , MIN(DECODE(no, 9,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "255"
     , MIN(DECODE(no,10,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "265"
     , MIN(DECODE(no,11,DECODE(rn,1,a_cnt,2,a_amt,3,b_cnt,4,b_amt,5,c_cnt,6,c_amt))) "275"
  FROM (SELECT a.card_bank_code
             , c.no
             , c.elec_cd
             , COUNT(CASE WHEN a.elec_cd  = c.elec_cd AND a.mgr_org  = c.elec_cd
                          THEN 1 END) a_cnt
             , COUNT(CASE WHEN a.elec_cd != c.elec_cd AND a.mgr_org  = c.elec_cd
                          THEN 1 END) b_cnt
             , COUNT(CASE WHEN a.elec_cd  = c.elec_cd AND a.mgr_org != c.elec_cd
                          THEN 1 END) c_cnt
             , NVL(SUM(CASE WHEN a.elec_cd  = c.elec_cd AND a.mgr_org  = c.elec_cd
                        THEN amt END) , 0) a_amt
             , NVL(SUM(CASE WHEN a.elec_cd != c.elec_cd AND a.mgr_org  = c.elec_cd
                        THEN amt END) , 0) b_amt
             , NVL(SUM(CASE WHEN a.elec_cd  = c.elec_cd AND a.mgr_org != c.elec_cd
                        THEN amt END) , 0) c_amt
          FROM (SELECT card_bank_code
                     , SUBSTR(elec_bill_num,1,3) elec_cd
                     , mgr_org
                     , COUNT(*) cnt
                     , SUM(card_settle_amt) amt
                  FROM card_man_tab
                 GROUP BY card_bank_code
                        , SUBSTR(elec_bill_num,1,3)
                        , mgr_org
                ) a
             , elec_code c
         GROUP BY a.card_bank_code
                , c.no
                , c.elec_cd
        ) aa
     , (SELECT ROWNUM rn FROM dual CONNECT BY LEVEL <= 6) cc
 GROUP BY aa.card_bank_code, cc.rn
 ORDER BY aa.card_bank_code, cc.rn

by 볼우물 [2008.09.01 16:54:33]
감사합니다. 저에겐 무척이나 버거운 쿼리문이네요... 몇일동안 보면서 이해를 해야 할듯.. 정말 감사합니다 ^^ 아 그리고 저 책 좀 추천해주실수 있나요?

by 마농 [2008.09.01 17:08:58]
일단 원하시는 폼은 만들어 드렸지만....
테스트도 안해봤구요. 잘 돌지 모르겠네요.
또한 문제가 없다 치더라도 대용량에서는 과부하가 걸릴만한 쿼리입니다.
성능을 장담할 수 없네요.

by 볼우물 [2008.09.01 17:26:01]
내 방금 인터넷에 Cartesian product라는 것을 검색해봤는데 과부하가걸릴수 있다고 하더군요.. 그리고 제가 이정도 수준의 쿼리를 우리 대리님께 보인다면 출처를 추궁할게 분명합니다ㅠ 그리고 jsp페이지에서는 한로우씩 읽어들이기 때문에.. 마농님이 짜주신 거는 활용을 못할듯 하네요.ㅠ 하지만 좋은 공부가 되었습니다^^
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입