DATOR


GROUP BY 결과 데이터 중 원하는 값 추출시 비효율제거. 튜닝[SQL]


 

아래와 같은 데이터가 있을때 어떤 번호별로 가장 큰금액값 에 대한 날짜를 가져오고 싶을때가 있습니다.

 

물론 다양한 여러가지 경우가 있을수 있겠습니다.

 

  SAMPLE1.jpg

 

00001 번에 대한 금액이 가장큰 3500원에 대한 날짜인 20110601 값을 가져와야 합니다.

 

단순히 아래와 같이 번호에 MAX(날짜), MAX(금액)  하면 원하는 값을 가져오지 못하겠죠.

 

SELECT NO, MAX(YMD), MAX(AMT)
  FROM (
     SELECT '00001' NO, '20110602' YMD, 2500 AMT FROM DUAL
     UNION ALL
     SELECT '00001' NO, '20110601' YMD, 3500 AMT FROM DUAL
     UNION ALL
     SELECT '00002' NO, '20110601' YMD, 5500 AMT FROM DUAL
     UNION ALL
     SELECT '00002' NO, '20110602' YMD, 6500 AMT FROM DUAL
     ) A
 GROUP BY NO

 

 SAMPLE2.jpg

 

다른 방법으로 아래와 같이 서브쿼리로 비교하여 가져올수 있습니다.

 

SELECT NO, YMD, AMT
  FROM (
       SELECT '00001' NO, '20110602' YMD, 2500 AMT FROM DUAL
       UNION ALL
       SELECT '00001' NO, '20110601' YMD, 3500 AMT FROM DUAL
       UNION ALL
       SELECT '00002' NO, '20110601' YMD, 5500 AMT FROM DUAL
       UNION ALL
       SELECT '00002' NO, '20110602' YMD, 6500 AMT FROM DUAL
       )
 WHERE (NO, AMT) IN (
                     SELECT NO, MAX(AMT)
                       FROM (
                             SELECT '00001' NO, '20110602' YMD, 2500 AMT FROM DUAL
                             UNION ALL
                             SELECT '00001' NO, '20110601' YMD, 3500 AMT FROM DUAL
                             UNION ALL
                             SELECT '00002' NO, '20110601' YMD, 5500 AMT FROM DUAL
                             UNION ALL
                             SELECT '00002' NO, '20110602' YMD, 6500 AMT FROM DUAL
                             ) A
                     GROUP BY NO
                     )

 

SAMPLE3.jpg

 

이방법은 답은 얻을수 있으나 같은 집합을 두번 Access 하는 비효율이 있습니다.

 

이런 경우 분석함수 사용을 통하여 비효율을 제거 할 수 있습니다.

 

SELECT X.NO, X.YMD, X.AMT
FROM (
 SELECT NO, YMD, AMT, MAX(AMT) OVER(PARTITION BY NO ORDER BY NO) AMT_B
 FROM (
       SELECT '00001' NO, '20110602' YMD, 2500 AMT FROM DUAL
       UNION ALL
       SELECT '00001' NO, '20110601' YMD, 3500 AMT FROM DUAL
       UNION ALL
       SELECT '00002' NO, '20110601' YMD, 5500 AMT FROM DUAL
       UNION ALL
       SELECT '00002' NO, '20110602' YMD, 6500 AMT FROM DUAL
      ) A
 GROUP BY NO, YMD, AMT
) X
WHERE X.AMT = X.AMT_B

 

SAMPLE3.jpg

 

같은 그룹에 해당하는 데이터중 원하는 값을 가져오고자 할때 사용합니다.

 

 

Tag :

Leave Comments