2012-11-14 4 views
4

저는 다시 GROUP BY으로 고생합니다. 내가 처리 할 수있는 기본 사항은 다음과 같습니다. group by에 이름이 지정된 다른 열을 어떻게 그룹화 할 수 있습니까? group by은 나만의 아이디어이며 더 잘 작동하는 것도있을 수 있습니다. 그것은 오라클에서 작동해야합니다.최대 계산에서 전체 행을 얻는 방법은 무엇입니까?

create table xxgroups (
    groupid int not null primary key, 
    groupname varchar2(10) 
); 
insert into xxgroups values(100, 'Group 100'); 
insert into xxgroups values(200, 'Group 200'); 

drop table xxdata; 
create table xxdata (
    num1 int, 
    num2 int, 
    state_a int, 
    state_b int, 
    groupid int, 
    foreign key (groupid) references xxgroups(groupid) 
); 
-- "ranks" are 90, 40, null, 70: 
insert into xxdata values(10, 10, 1, 4, 100); 
insert into xxdata values(10, 10, 0, 4, 200); 
insert into xxdata values(11, 11, 0, 3, 100); 
insert into xxdata values(20, 22, 5, 7, 200); 

작업은 각 distinct (num1, num2)에 대한 결과 행을 생성하고 인쇄하는 것입니다 state_astate_b에서 가장 높은 계산 "순위"와 groupname이 :

은 여기 내 예입니다. 인 "그룹 (200)의"groupname로 - 처음 두 행이 동일한 num S를 따라서 만 높은 순위가 선택되어야한다는

참고.

나는 아주 기본적인 group by을 얻었습니다. 나는에 groupname 원하는 완벽한

nummer ranking 
---------------- 
1010  90 
1111  
2022  70 

100 %

nummer groupname 
------------------- 
1010  Group 100 
1111  Group 100 
2022  Group 200 
  • 까다로운 부분은 다음과 같습니다

    SELECT xd.num1||xd.num2 nummer, max(ranking.goodness) 
    FROM xxdata xd 
        , xxgroups xg 
        ,(select state_a, state_b, r as goodness 
         from dual 
         model return updated rows 
         dimension by (0 state_a, 0 state_b) measures (0 r) 
         rules (r[1,4]=90, r[3,7]=80,r[5,7]=70, r[4,7]=60, r[0,7]=50, r[0,4]=40) 
         order by goodness desc 
        ) ranking 
    WHERE xd.groupid=xg.groupid 
        and ranking.state_a (+) = xd.state_a 
        and ranking.state_b (+) = xd.state_b 
    GROUP BY xd.num1||xd.num2 
    ORDER BY nummer 
    ; 
    

    결과는 90 내가 무엇을 필요 %입니다 결과. (나는이 모든 그룹에서 온 최고의 순위 항목을 선택하지 것이다) 나는 하지 희망을

  • 을 - 그때 뿐만 아니라 group by에 넣어있을 것 때문에 나는 select에 포함 할 수 없습니다
  • 내 솔루션에서 "순위"를 계산하려면 model 테이블을 사용하십시오. 내가 확신하는 다른 해결책이있다. 요점은, 내가 두 번하고 싶지 않은 것이 사소한 계산이라는 것입니다.
  • 다른 예제에서 두 번째 쿼리를 사용하여 원래 행으로 돌아가서 groupname에 도착할 수 있음을 알고 있습니다. 그러나 여기에서 할 수있는 것은 내 순위 계산을 복제하지 않고 입니다.
  • group byLIMIT 1/ORDER BY goodness으로 바꾸고이 계산 선택을 필터링 subselect로 사용하는 것이 좋습니다. 그러나 a) 오라클에 LIMIT이없고, rownum<=1이 subselect에서 수행 할 수 있을지 의심스럽고 b) 어쨌든 내 뇌를 감쌀 수 없습니다. 어쩌면 방법이 있을까요?

답변

4

당신은 선택적으로 그룹의 행의 하위 집합 위에 기능을 적용 할 FIRST 집계 수정을 사용할 수 있습니다 .... select에서 over이 excactly 무엇을 이해하려고해야합니다 - 여기에 하나의 행 (SQLFiddle demo) : 분석과

SELECT xd.num1||xd.num2 nummer, 
     MAX(xg.groupname) KEEP (DENSE_RANK FIRST 
           ORDER BY ranking.goodness DESC) grp, 
     max(ranking.goodness) 
FROM xxdata xd 
    , xxgroups xg 
    ,(select state_a, state_b, r as goodness 
     from dual 
     model return updated rows 
     dimension by (0 state_a, 0 state_b) measures (0 r) 
     rules (r[1,4]=90, r[3,7]=80,r[5,7]=70, r[4,7]=60, r[0,7]=50, r[0,4]=40) 
     order by goodness desc 
    ) ranking 
WHERE xd.groupid=xg.groupid 
    and ranking.state_a (+) = xd.state_a 
    and ranking.state_b (+) = xd.state_b 
GROUP BY xd.num1||xd.num2 
ORDER BY nummer; 

귀하의 방법은 잘 작동하지만, 우리는 이미 여기에 집계를 사용하기 때문에, 우리는뿐만 아니라 한 번에 모든 열을 얻을 수있는 FIRST 수정을 사용할 수 있습니다.

+0

흥미 롭습니다. 'KEEP'과'FIRST'에 대한 문서를 살펴볼 것입니다. 내 계산에 맞춰 계산 작업이 다른 열에서 수행되는 곳에서 'max()'를 적용한다는 것이 맞습니까? 나는. 'max (xg.groupname)'자체는 의미가 없기 때문에 오라클에 "최대 우선 순위를 참조하십시오. 우선 순위 결과를 사용하여 dense_ranking을 참조하십시오." 이것은 "다른 사람의 열망을 원한다"라는 문제에 대한 일반적인 해결책처럼 들린다. – towi

+0

예, 오라클은'goodness'가 최대 인 행에만'MAX (groupname)'함수를 적용 할 수 있습니다. 본질적으로 '선'이 고유하면 다른 열의 최대 값을 가진 행의 열을 선택할 수 있습니다. –

+0

좋습니다. [this docu] (http://www.oracle-base.com/articles/misc/rank-dense-rank-first-last-analytic-functions.php)를 통해 나는 'FIRST'를 쉽게 이해할 수 있습니다. 그것은 내가'그룹 바이 '를'over by (by partition by ...)'로 대체 할 수 있다고 제안하지 않습니까? – towi

2

와우, 전에 검색했지만, 지금은 this answer을 찾았습니다.이 질문을 제가 제 질문에 적용 할 수있었습니다. 오라클 솔루션은 여기에, over입니다 order byrow_number()partition by :

select * 
from (select data.*, row_number() 
     over (partition by nummer order by goodness desc) as seqnum 
from (
SELECT xd.num1, xd.num2 nummer, xg.groupname, ranking.goodness 
FROM xxdata xd 
    , xxgroups xg 
    ,(select state_a, state_b, r as goodness 
     from dual 
     model return updated rows 
     dimension by (0 state_a, 0 state_b) measures (0 r) 
     rules (r[1,4]=90, r[3,7]=80,r[5,7]=70, r[4,7]=60, r[0,7]=50, r[0,4]=40) 
    ) ranking 
WHERE xd.groupid=xg.groupid 
    and ranking.state_a (+) = xd.state_a 
    and ranking.state_b (+) = xd.state_b 
ORDER BY nummer 
) data) 
where seqnum = 1 
; 

결과는 아름다운

10   10 Group 100   90   1 
    11   11 Group 100      1 
    20   22 Group 200   70   1 

입니다.

지금은

관련 문제