2011-08-24 2 views
1

이것은 공식화하는 데 어려운 질문입니다. (모든 편집은 인정됩니다) 그러나 여기에 있습니다. 두 테이블 (FRUITBASKET)이 있다고 가정 해 보겠습니다. 과일 (과일류가 아닌 실제 아이템을 나타냄)은 바구니로 그룹화됩니다.레코드의 속성이 GROUP BY 문의 무언가의 MAX입니까?

FRUIT_ID WEIGHT_IN_GRAMS BASKET_ID FRUIT_TYPE 
-------- --------------- --------- ---------- 
1   100    1   Apple  
2   200    1   Orange  
3   150    1   Lemon  
4   100    2   Apple 
5   300    2   Plum 

내가 원하는 것은 각 바구니에서 무거운 과일의 FRUIT_ID입니다 : 여기에 FRUIT의 한 예입니다. 즉 : 그 WEIGHT_IN_GRAMS 제외

select fruit_id, basket_id, fruit_type 
    from fruit f 
    join (select basket_id, max(weight_in_grams) max_weight 
      from fruit 
     group by basket_id) t on f.basket_id = t.basket_id 
           and f.weight_in_grams = t.max_weight; 

이 일할 수있는이 고유 보장되지 않습니다 : 여기에

FRUIT_ID BASKET_ID FRUIT_TYPE 
-------- --------- ---------- 
2   1   Orange 
5   2   Plum 

내가이를 찾기 위해 마련 한 SQL이다. 중복이있는 경우, 나는 알파벳 순서대로 마지막 것을 원할 것입니다.

수취인?

PS : 위의 쿼리를 위의 다른 쿼리로 래핑 할 수 있다는 것을 알고 있습니다. 그러나 이것은 다소 지저분 해 보입니다. 가능한 경우 가능한 한이를 최적화하는 것이 좋습니다.

+0

귀하의 농구 테이블이이 모든 것에 어떻게 들어 맞는지는 실제로 볼 수 없습니다. FRUIT에 FRUIT에 가입하는 것 같습니다. 각 테이블의 정확한 정의를 게시 할 수 있습니까? – DCookie

+0

바스켓 테이블은 실제로 과일을 임의로 그룹화 한 것입니다. 이것은 내가 가진 실제 문제에 대한 비유이며,이 문제는이 문제를 더욱 이해하기 어렵게 만듭니다. – daveslab

답변

4

dense_rank를 사용하여 각 행에 번호를 할당 할 수 있습니다. partition by은 자체 시퀀스 (이 경우 각 바구니)가있는 그룹을 만듭니다. order by은 정렬을 지정하므로 가중치로 먼저 정렬 (내림차순)하고 이름을 두 번째로 정렬합니다.

각 바구니의 첫 번째 행에 숫자 1이옵니다. 그런 다음 숫자가 1 인 행만 선택할 수 있도록 쿼리를 래핑합니다. 분석 함수를 사용할 수 없으므로 하위 쿼리에서이 작업을 수행해야합니다 where 절에서, having 절에서도, 나는 믿습니다.

select 
    fruit_id, basket_id, fruit_type, weight_in_grams 
from 
    (select 
     fruit_id, basket_id, fruit_type, weight_in_grams, 
     dense_rank() over (partition by basket_id order by weight_in_grams desc, fruit_type desc) as rank 
    from 
     fruit f) 
where 
    rank = 1 
+0

OVER 절에있는 fruit_type DESC를 정렬하지 않으므로 가중치와 관련하여 마지막으로 알파벳순으로 구할 수 있습니다. – DCookie

+0

@DCookie. 감사. 나는 그 질문에서 '마지막'을 간과 한 것 같다. :) 고쳤다. – GolezTrol

+0

오라클은 독점적 인 마법으로 놀라움을 멈추지 않습니다. 감사! – daveslab