Select와 Unionall사용한 쿼리 질문입니다 0 8 1,508

by 이상민 [2007.05.30 15:55:49]


------------------------------------------------------------------------------

SELECT n.cust_id,
                  AF_GET_CUST_NAME(p_corp_id, n.cust_id) AS cust_name,
                  n.name_gubun,
                  sum(n.tbill_qty) AS tbill_qty,
                  sum(n.supp_amt) AS supp_amt
              FROM  (
                   SELECT a.cust_id,
                      c.name_gubun,
                       tbill_qty,
                      supp_amt
                    FROM  AT_STAX_BILL a,
                      AT_STBILL_ITEM b,
                      AV_CITEM_NAME c
                   WHERE a.corp_id   = p_corp_id
                   AND   a.sect_id   = p_sect_id
                   AND   a.tbill_yymm  BETWEEN p_fr_yymm AND p_to_yymm
                   AND   a.corp_id   = b.corp_id
                   AND   a.sect_id   = b.sect_id
                   AND   a.tbill_yymm = b.tbill_yymm
                   AND   a.tbill_no   = b.tbill_no
                   AND   b.tax_item   = c.item_id

                   UNION  ALL
                   SELECT distinct
                      a.cust_id,
                      c.name_gubun,
                      0 AS tbill_qty,
                      0 AS supp_amt
                   FROM  AT_STAX_BILL a,
                       AT_STBILL_ITEM b,
                       AV_CITEM_NAME c
                   WHERE  a.corp_id   = p_corp_id
                   AND   a.sect_id   = p_sect_id
                   AND   a.tbill_yymm  BETWEEN p_fr_yymm AND p_to_yymm
                   AND   a.corp_id   = b.corp_id
                   AND   a.sect_id   = b.sect_id
                   AND   a.tbill_yymm  = b.tbill_yymm
                   AND   a.tbill_no   = b.tbill_no
                  )n
              GROUP BY n.cust_id, n.name_gubun

--------------------------------------------------------------------------

비슷한 식의 Select문을 union all로해서 합쳐서 이 상위 질의에서 그룹을 시킵니다.

 

하는 이유는....값이 없는 Row에 대해서도 보여주기 위해서인걸로 아는데.

 

이방법 말고 다른 방법은 없을까해서 이렇게 글을 남겨봅니다

 

정답을 원한다기보다^^참고할수 있는 코멘트만으로도 전 만족합니다.

 

오늘 오후도 덥네요 다들^^시원한 하루 보내세요!

 

by finecomp [2007.05.30 00:00:00]
UNION ALL기준으로 아래의 쿼리는 카테시안 곱으로 (a, b조인한 결과 row) * c전체의 row만큼 생깁니다.
아래결과를 실행하시어 UNION ALL한 결과와 비교해 보시기 바랍니다.
같으면 UNION ALL을 과감히 빼세요...^^;
SELECT a.cust_id,
c.name_gubun,
tbill_qty,
supp_amt
FROM AT_STAX_BILL a,
AT_STBILL_ITEM b,
AV_CITEM_NAME c
WHERE a.corp_id = p_corp_id
AND a.sect_id = p_sect_id
AND a.tbill_yymm BETWEEN p_fr_yymm AND p_to_yymm
AND a.corp_id = b.corp_id
AND a.sect_id = b.sect_id
AND a.tbill_yymm = b.tbill_yymm
AND a.tbill_no = b.tbill_no
AND b.tax_item = c.item_id(+)

건승하시길...수고하세요~~

by 현 [2007.05.30 00:00:00]
잘은 모르겠으나 저 쿼리는 잘못된 쿼리인 듯 보입니다.
인라인 뷰 안에 있는 union all 밑에 부분 쿼리에서 AV_CITEM_NAME c 테이블에 대한 조인이 카티션 프러덕트로 되어 있네요.
그러다 보니 중복이 많이 발생해서 그걸 줄이고자 distinct 를 사용한 것 같은데요.
이렇게 하시면 안됩니다.
만약 b.tax_item에 대응하는 값이 C테이블에 없을 경우에도 나오게 해야 한다면 C테이블에 대해서 아우터조인을 거세요...

by 현 [2007.05.30 00:00:00]
답글을 다는 동안 finecomp 님께서 답을 해 주셨네요.
제 생각이 바로 저것입니다만 finecomp 님께서 하신 것에는 SUM이 없네요.
SELECT a.cust_id,
c.name_gubun,
SUM(tbill_qty),
SUM(supp_amt )
FROM AT_STAX_BILL a,
AT_STBILL_ITEM b,
AV_CITEM_NAME c
WHERE a.corp_id = p_corp_id
AND a.sect_id = p_sect_id
AND a.tbill_yymm BETWEEN p_fr_yymm AND p_to_yymm
AND a.corp_id = b.corp_id
AND a.sect_id = b.sect_id
AND a.tbill_yymm = b.tbill_yymm
AND a.tbill_no = b.tbill_no
AND b.tax_item = c.item_id(+)
GROUP BY a.cust_id, c.name_gubun

이것과 답이 틀린지 확인 함 해보세요...

by finecomp [2007.05.30 00:00:00]
또한 GROUP BY n.cust_id, n.name_gubun한 결과 row가 얼마 안된다면 문제가 크지 않겠지만, 추후라도 이 결과가 많아질 가능성이 있다면 cust_name을 함수로 가져오는 것은 비효율적인 방법입니다.
거의 row수만큼 무조건 함수내의 테이블을 반복 access하여 수행됩니다.

단순한 코드명이라면 스칼라서브쿼리를
고객명처럼 결과내에서 종류가 다양하다면 조인을 고려 해 보세요...;

by 이상민 [2007.05.30 00:00:00]
우와 답변들^^감사합니다!!
일단 아우터 조인의경우에는..
tbill_qty의 값과 supp_amt값이 ;나오더라구요

^^ 좋은하루되세요~

by finecomp [2007.05.30 00:00:00]
아~~일단 UNION ALL부분과만 대치하여 실행하고 느껴보시라고 최적화는 안했습니다...^^;

by 이상민 [2007.05.30 00:00:00]
그세 답들이;;감사합니다^^실행해볼게요~!

by 이상민 [2007.05.30 00:00:00]
역시 쉽지않네요^^ㅋ 여튼 다들 감사드립니다!
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입