PARTITION BY 사용 쿼리를 다른걸로 바꾸기.. 0 4 3,132

by 허용운 [2007.08.03 10:23:26]


WITH t AS (
   SELECT 'E000001732695' AS ITEM_ID,  '1772' AS PROMO_ID, '820' AS AMT FROM DUAL
  UNION ALL
   SELECT 'E000001732921' AS ITEM_ID,  '1772' AS PROMO_ID, '13200' AS AMT FROM DUAL         
  UNION ALL
   SELECT 'E000005174450' AS ITEM_ID,  '1772' AS PROMO_ID, '5' AS AMT FROM DUAL
  UNION ALL
   SELECT 'E000001732923' AS ITEM_ID,  '1772' AS PROMO_ID, '1310' AS AMT FROM DUAL          
  UNION ALL
   SELECT 'E000001732930' AS ITEM_ID,  '1773' AS PROMO_ID, '1500' AS AMT FROM DUAL 
  UNION ALL
   SELECT 'E000001732959' AS ITEM_ID,  '1773' AS PROMO_ID, '6000' AS AMT FROM DUAL 
  UNION ALL
   SELECT 'E000001732940' AS ITEM_ID,  '1773' AS PROMO_ID, '10000' AS AMT FROM DUAL 
  UNION ALL
   SELECT 'E000001732980' AS ITEM_ID,  '1774' AS PROMO_ID, '800' AS AMT FROM DUAL
  UNION ALL
   SELECT 'E000001732910' AS ITEM_ID,  '1774' AS PROMO_ID, '900' AS AMT FROM DUAL )                  
SELECT * FROM t

위테이블에서 결과가

ITEM_ID      PROMO_ID  AMT
E000001732921 1772 13200
E000001732940 1773  6000
E000001732910 1774  900


PROMO_ID 별로 가장큰 AMT를 구하는 겁니다.

 

일단은

 

SELECT * FROM (
 SELECT  ITEM_ID, PROMO_ID, AMT
          ,ROW_NUMBER() OVER (PARTITION BY PROMO_ID ORDER BY AMT DESC ) RNUM
 FROM t
)
WHERE RNUM = 1

이렇게 처리 했는데.. 보기도 않좋고 해서요

혹시 다른 좋은 방법 있으시면 가르켜 주세요.

 

게다가 파티션 바이 특성상.. 오라클에서 밖에 못쓸거 같고. : (

 

 

by finecomp [2007.08.03 00:00:00]
한 쿼리로 어떤 상황에서건 모두 만족하는 쿼리는 거의 없습니다.
위 쿼리가 왜 보기가 안좋다는지는 모르겠지만,
위 요구사항을 풀려면 분석함수를 지원하지 않는 DBMS에선 Self Join등을 동원하여 추가로 테이블을 한번이상 더 scan 해야 가능합니다.

성능에선 비효율이 분명 생기는 것이죠.
순위정도로 Q&A검색하면 Self-Join을 이용한 방법이 많이 나올겁니다.
비효율이라도 좋다 어떤 상황에서건 나만 편하면 된다라고 생각하신다면 검색하여 적용하시면 되겠습니다...말이 심하다면 죄송...저로서는 잘 이해가 안되는 마인드라서요...;
예를 들어 각 랭귀지의 특징은 무시하고 VB와 파워빌더에 다 통용되는 소스코드를 찾는 것과 유사해 보입니다...;

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

by finecomp [2007.08.03 00:00:00]
참고로 MSSQL 2005이상 버전에서도 분석함수를 지원하고 있습니다...점차 확산되면 되었지 사장되지는 않을 함수인 듯 한데요...^^;

by 마농 [2007.08.03 00:00:00]
1. Self Join
SELECT * FROM t
WHERE (promo_id, amt) IN (SELECT promo_id, MAX(amt) FROM t GROUP BY promo_id)
2. 문자열 붙여 MAX 후 substring
SELECT SUBSTR(MAX(LPAD(amt,10,'0')||item_id),11) item_id
, promo_id
, MAX(amt) amt
FROM t
GROUP BY promo_id

by 허용운 [2007.08.03 00:00:00]
그런가요?
그럼 다행이네요. 머리에 당장 떠오르는게 저거라서
그냥 썼는데.. 쿼리 바꾸라고 말한 사람한테
finecomp 님이 말한대로 설명 하면 되겠네요.
: )
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입