2009-09-13 3 views
1

행의 순위/번호를 찾고 싶습니다. 나는 잘 설명 할 수 있을지 잘 모르겠다.mysql 합계를 기반으로 행의 순위를 찾는 방법은 무엇입니까?

나는

$sql = 'SELECT SUM(amount) AS total FROM sales ORDER BY total DESC'; 

$res = mysql_query($sql); 

while($row = mysql_fetch_array($res)) { 

// go through and print each row biggest 'total' first 
echo $row['total'] . '<br />'; 

} 

가 지금은 통과하고 가장 큰 '전체'수 인에 따라 각 순위를 부여 할 쿼리를 가지고 '1'.

그래서 나는 몇 가지 계산을 수행하여 PHP로 그 작업을 수행 할 수 있습니다

$sql = 'SELECT SUM(amount) AS total FROM sales ORDER BY total DESC'; 

$res = mysql_query($sql); 

$rank = 1; 

while($row = mysql_fetch_array($res)) { 



// go through and print each row biggest 'total' first 
echo 'rank: ' . $rank . ', ' . $row['total'] . '<br />'; 

$rank = $rank + 1; 

} 

이것은 좋은 일입니다. 하지만 내가하고 싶은, 판매 테이블에서 제휴사 ID를 말을 기반으로 SQL 쿼리를 할 수 있도록 PHP없이 행의 순위를 결정할 수있을 것입니다.

예를 들어, 각 행에 제휴사 ID가 연결된 판매 데이터 행이 100 개있는 경우 가장 큰 합계를 가진 제휴사를 기준으로 순위를 얻는 방법을 간단히 알 수 있습니까?

답변

1

당신과 같이,이 작업을 수행하는 재귀 변수를 사용할 수 있습니다

select 
    @rownum:[email protected]+1 as rank, 
    sum(amount) as total 
from 
    sales, 
    (select @rownum:=0) a 
order by total desc 

가 특정 계열사의 순위를 잡아, 당신은해야 할 것 :

select 
    a.*, 
    t.rank, 
    t.total 
from 
    affiliates a 
    inner join (
     select 
      @rownum:[email protected]+1 as rank, 
      affiliate_id, 
      sum(amount) as total 
     from 
      sales, 
      (select @rownum:=0) r 
     group by affiliate_id 
     order by total desc) t on 
     a.affiliate_id = t.affiliate_id 
where 
    a.affiliate_id = 342 

을 이제 그건 (상대적으로) 느린 이유는 매번 테이블 스캔을해야하기 때문입니다.

MySQL을 사용하지 않았다면 하위 쿼리를 제안 하겠지만, 대용량 MySQL은 하위 쿼리를 무서워 최적화합니다. 그것은 나에게 상당히 느린 것처럼 보이지만 나는 그것을 벤치마킹하지 않았다. 어쨌든, 당신은이 작업을 수행 할 수 있습니다

select 
    a.*, 
    (select 
     count(*)+1 
    from 
     (select affiliate_id from sales 
     group by affiliate_id having sum(amount) > 
      (select sum(amount) from sales where affiliate_id = a.affiliate_id))) 
     as rank 
from 
    affiliates a 
where 
    a.affiliate_id = 342 
+0

drats, 나는 너무 늦었다. –

+0

좋아 보인다. 하지만 성능에 영향을 줍니까? – mauris

+0

@Mauris : 아니오, 의미있는 방법은 아닙니다. 밀리 초 또는 2 오버 헤드가 될 수 있지만 벤치마킹 한대로 말할 수는 없습니다 (필요성을 느끼지 못함). – Eric

-1

다른 구현을 DB는 ROW_NUMBER와 row_number_count있다의. MySQL을 사용하고 있다면, 이걸 보길 바란다. walk-around

관련 문제