여러 테이블 Outer Join 질문드려요.ㅜ.ㅜ 0 4 2,469

by DB초보 [2015.03.13 13:33:26]


캡처.PNG (4,778Bytes)

안녕하세요~

복수의 테이블을 Outer Join을 하려는데 원하는 데이터가 나오지 않네요;;

현재 C(THISMT)와 E(STACKMT)의 서브쿼리에만 데이터가 있고, 나머지는 데이터가 없이 Outer Join으로 해당 열에만 데이터가 나오게 할

계획입니다.

그런데 Outer Join을 여러번하니 마지막 열인 STACKMT에만 데이터가 나오고 THISMT에는 안나오네요;;;

D까지는 조인을 하고 E는 주석처리하면 C(THISMT)에 데이터가 잘 나옵니다....ㅜ.ㅜ

 

SELECT A.SPMON AS SPMON
, ROUND(A.YP_SALE / 1000000,0) AS YEARP
, ROUND(B.M_ZSALE_P / 1000000,0) AS THISMP
, ROUND(C.M_ZSALE_T / 1000000,0) AS THISMT
, ROUND(D.Y_ZSALE_P / 1000000,0) AS STACKMP
, ROUND(E.Y_ZSALE_T / 1000000,0) AS STACKMT
FROM(
            SELECT SUBSTR (A.SPMON, 1, 4) AS SPMON
                           , SUM(A.ZSALE) AS YP_SALE
                           , B.VKORG_N2 AS VKORG
           FROM R3DKPDATA.ZEIST_CO_01 A, R3DKPDATA.ZEIST_ZM_01 B
                  WHERE A.MANDT = '100'
                    AND A.BUKRS= '5000'
                      AND A.SPMON BETWEEN '201501' and '201512'
                      AND A.PLIKZ='1'
                           AND A.MANDT = B.MANDT
                           AND A.BUKRS = B.BUKRS
                           AND A.VKORG = B.VKORG
                  GROUP BY SUBSTR (A.SPMON, 1, 4), B.VKORG_N2
                 ) A
         LEFT OUTER JOIN
  (
  SELECT SUBSTR (A.SPMON, 1, 4) AS SPMON ,
  SUM(A.ZPRF2) AS M_ZSALE_P
  , B.VKORG_N2 AS VKORG
  FROM r3dkpdata.ZEIST_CO_01 A, r3dkpdata.ZEIST_ZM_01 B
  WHERE A.MANDT = '100' AND A.BUKRS= '5000' AND A.SPMON = '201502' AND A.PLIKZ='1'
  AND A.MANDT = B.MANDT AND A.BUKRS = B.BUKRS AND A.VKORG = B.VKORG
  GROUP BY SUBSTR (A.SPMON, 1, 4), B.VKORG_N2
   ) B
   ON A.SPMON = B.SPMON
   AND A.VKORG = B.VKORG
   RIGHT OUTER JOIN
    (
    SELECT SUBSTR (A.SPMON, 1, 4) AS SPMON
    , SUM(A.ZPRF2) AS M_ZSALE_T
    , B.VKORG_N2 AS VKORG
    FROM r3dkpdata.ZEIST_CO_01 A, r3dkpdata.ZEIST_ZM_01 B WHERE A.MANDT = '100' AND A.BUKRS= '5000'
    AND A.SPMON = '201502' AND A.PLIKZ='0' AND A.MANDT = B.MANDT AND A.BUKRS = B.BUKRS AND A.VKORG = B.VKORG
    GROUP BY SUBSTR (A.SPMON, 1, 4), B.VKORG_N2
   ) C
   ON B.SPMON = C.SPMON
   AND B.VKORG = C.VKORG
   LEFT OUTER JOIN
    (
    SELECT SUBSTR (A.SPMON, 1, 4) AS SPMON ,
     SUM(A.ZPRF2) AS Y_ZSALE_P
    , B.VKORG_N2 AS VKORG
   FROM r3dkpdata.ZEIST_CO_01 A, r3dkpdata.ZEIST_ZM_01 B
   WHERE A.MANDT = '100' AND A.BUKRS= '5000' AND A.SPMON BETWEEN '201501' AND '201502' AND A.PLIKZ='1'
   AND A.MANDT = B.MANDT AND A.BUKRS = B.BUKRS AND A.VKORG = B.VKORG
   GROUP BY SUBSTR (A.SPMON, 1, 4), B.VKORG_N2
   ) D
   ON C.SPMON = D.SPMON
   AND C.VKORG = D.VKORG
   RIGHT OUTER JOIN
   (
   SELECT SUBSTR (A.SPMON, 1, 4) AS SPMON
   , SUM(A.ZPRF2) AS Y_ZSALE_T
   , B.VKORG_N2 AS VKORG
   FROM r3dkpdata.ZEIST_CO_01 A, r3dkpdata.ZEIST_ZM_01 B
   WHERE A.MANDT = '100' AND A.BUKRS= '5000' AND A.SPMON BETWEEN '201501' AND '201502'
   AND A.PLIKZ='0' AND A.MANDT = B.MANDT AND A.BUKRS = B.BUKRS AND A.VKORG = B.VKORG
   GROUP BY SUBSTR (A.SPMON, 1, 4), B.VKORG_N2
   ) E
   ON D.SPMON = E.SPMON
   AND D.VKORG = E.VKORG

 

 아직 많이 부족해서 잘 모르겠어요..ㅜ.ㅜ

고수님들 답변 부탁드립니다!!

 

 

by 마농 [2015.03.13 14:25:57]

아우터 조인을 LEFT 와 RIGHT 를 섞어 놓으니...
쿼리에 익숙한 저조차도 이해하기 힘드네요...
한가지만 통일해서 사용하는 것이 좋을 것 같구요.
그러나 이문제는 아우터 조인을 해결할 문제가 아닙니다.
쿼리의 비효율을 제거해야 하는 문제이구요.
비효율을 제거하면 아우터 조인은 필요 없어집니다.
동일 테이블을 여러번 읽는 구조네요...
공통조건은 Where 절에 남기고, 개별조건은 Case 로 처리하면 한방에 됩니다.
 

SELECT SUBSTR(a.spmon, 1, 4) AS spmon
     , b.vkorg_n2            AS vkorg
     , SUM(CASE WHEN                        a.plikz = '1' THEN a.zsale END) AS yp_sale
     , SUM(CASE WHEN a.spmon = '201502' AND a.plikz = '1' THEN a.zprf2 END) AS m_zsale_p
     , SUM(CASE WHEN a.spmon = '201502' AND a.plikz = '0' THEN a.zprf2 END) AS m_zsale_t
     , SUM(CASE WHEN                        a.plikz = '1' THEN a.zprf2 END) AS y_zsale_p
     , SUM(CASE WHEN                        a.plikz = '0' THEN a.zprf2 END) AS y_zsale_t
  FROM r3dkpdata.zeist_co_01 a
     , r3dkpdata.zeist_zm_01 b
 WHERE a.mandt = '100'
   AND a.bukrs = '5000'
   AND a.spmon BETWEEN '201501' AND '201512'
   AND a.plikz IN ('0', '1')
   AND a.mandt = b.mandt
   AND a.bukrs = b.bukrs
   AND a.vkorg = b.vkorg
 GROUP BY SUBSTR(a.spmon, 1, 4), b.vkorg_n2
;

 


by DB초보 [2015.03.13 15:14:10]

헉!!! 감사합니다!!!! 이렇게 쉽게 쿼리가 짜지다니.....

덕분에 머리가 띵해지면서 정말 부족하다는걸 많이 느끼게 됩니다~

그리고 질문이 한가지 더 있는데요...지금 저 결과값 중 m_zsale_t값에서 m_zsale_p값을 나눈 값을

넣는 컬럼을 추가하려 하는데요. 자꾸 데이터가 0또는 1로만 들어가네요...아무래도 나눈 다음 몫에 해당

하는 값만 넣는거 같습니다...ㅜ.ㅜ 실제로는 값이 0.xx, 1.xx 이래 나와서 그 나온 결과값에 *100을 해주려는 거거든요....

, ROUND((SUM(CASE WHEN a.spmon = '201412' AND a.plikz = '0' THEN a.zsale END) / SUM(CASE WHEN a.spmon = '201412' AND a.plikz = '1' THEN a.zsale END)),2) * 100 AS SUCCESS1

이렇게 구현하는데 안되네요;;


by 마농 [2015.03.13 15:27:46]

1. 실제 나온 값으로 다시 계산기로 돌려보세요.
  - 원래의 값이 0.xx 정도의 작은 값이라면 충분히 가능한 결과로 보여지네요.
2. 나누셈 할 때 주의 사항
  - 0 으로 나누면 에러납니다.
  - 회피방법 : 0 을 널로 치환하여 계산하세요.
  - a / b  ====> a / NULLIF(b, 0)
3. 구문중 THEN 절에 오는 항목이 a.zsale 이네요?
  - 혹시 a.zprf2 을 a.zsale 로 잘못 적은것은 아닐런지?


by DB초보 [2015.03.13 16:37:48]

아..가능한 결과군요...다시 한번 연구해봐야겠습니다!

예를 들어 40000 / 38000 X 100해서 105의 숫자가 나오는 식으로 하려했는데....

더 고민해봐야겠습니다~ 답변 감사합니다^^

그리고 a.zsale은 a.zprf2로 수정했습니다^^

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