2014-12-19 3 views
0

업데이트 :서수 순위는이 같은 테이블을 가지고

id name incidence placeRef 
1  John 10   1 
2  Ann  9   1 
3  Paul 9   1 
4  Carl 8   1 
5  John 4   1 
6  Ann  4   1 
7  Paul 7   1 
8  Carl 1   1 

나는 이것들이 ordinal ranking method를 사용하여 순위를합니다. 어떤 식으로 순위표를 추가 할 수 있습니까?

id name incidence placeRef rank 
1  John 10   1   1 
2  Ann  9   1   2 
3  Paul 9   1   2 
4  Carl 8   1   4 
5  John 4   1   2 
6  Ann  4   1   2 
7  Paul 7   1   1 
8  Carl 1   1   4 

어떻게 달성 할 수 있습니까?

N.B. 나는 내 자신의 질문에 답할 것이지만 조금이라도 더 나은 해결책을 가진 사람이 있는지 알고 싶다. 이 상황에서 해킹을 추천하는 수많은 게시물을 발견했지만.

+0

SQL 문은 어디에 있습니까? – Raptor

+0

주석을 달려면 잠시만 기다려주세요. –

답변

1

다음 작품 :

UPDATE names 
JOIN (SELECT * FROM names ORDER BY placeRef, incidence DESC) AS p ON p.id = names.id, 
(SELECT @curRank := 0, @nextRank := 0, @prevInc := 9999999999, @prevPlace := 0) AS v 
SET 
names.rank = IF( @prevPlace != p.placeRef, @curRank := 0, 0), 
names.rank = IF( @prevPlace != p.placeRef, @nextRank := 0, 0), 
names.rank = IF( @prevInc = p.incidence, @nextRank := @nextRank + 1, @curRank := @nextRank := @nextRank + 1), 
names.rank = IF( @prevInc = p.incidence, @curRank := @curRank, @curRank := @nextRank), 
names.incidence = @prevInc := names.incidence, 
names.placeRef = @prevPlace := names.placeRef; 

설명 :

UPDATE names 

1 - 그래서,이 주문 결과에 대한 가상 테이블을 만드는 - 테이블을 설정은

JOIN (SELECT * FROM names ORDER BY placeRef, incidence DESC) AS p ON p.id = names.id, 

2

를 업데이트 할 해당 순위를 적용 할 수 있습니다.

(SELECT @curRank := 0, @nextRank := 0, @prevInc := 9999999999, @prevPlace := 0) AS v 

3 - 이것은 계급

names.rank = IF( @prevPlace != p.placeRef, @curRank := 0, 0), 

4 incrament 때 말해 재설정하는 데 사용되는 몇 가지 변수를 설정 -이 0으로 현재의 순위를 재설정 해킹이 때 새로운 장소

에 MySQL의 반복 이것은 다음과 curre을 업데이트하는 해킹입니다 - 은
names.rank = IF( @prevPlace != p.placeRef, @nextRank := 0, 0), 

5 - 새로운 장소

names.rank = IF( @prevInc = p.incidence, @nextRank := @nextRank + 1, @curRank := @nextRank := @nextRank + 1), 

6에 MySQL의 반복이 때 0으로 다음 순위를 재설정 해킹 현재 발생 이전 발생

names.rank = IF( @prevInc = p.incidence, @curRank := @curRank, @curRank := @nextRank), 

7과 동일 할 때 NT가 위 - 그 발생 빈도는 이전과 동일하거나 외설 경우 순위를 증가 할 때 '마지막 순위와 동일로 순위를 설정 t

names.incidence = @prevInc := names.incidence, 

8 -이 이전 발생을 포함하는 변수를 설정하는 해킹, 그래서 우리는 다음 itteration

names.placeRef = @prevPlace := names.placeRef; 

9 무엇을 말할 수있다 -이 해킹 t이다 hat은 이전 위치를 포함하도록 변수를 설정하므로 다음 반복에서 수행 할 작업을 결정할 수 있습니다.

2

변수 또는 상관 된 하위 쿼리를 사용하여이 작업을 수행 할 수 있습니다.하위 쿼리 방법은 다음과 같습니다

select t.*, 
     (@rn := if(@i = t.incidence, if(@cnt := @cnt + 1, @rn, @rn), 
        @cnt + if(@i := t.incidence, if(@cnt := 1, @rn, @rn), @rn) 
        ) 
     ) as rank 
    from table t cross join 
     (select @i := 0, @rn := 0, @cnt := 1) vars 
    order by incidence desc; 

편집 :

만약 당신이 주어진 값과 일치하는 행의 수를 기억하기 때문에

select t.*, 
     (select 1 + count(t2.incidence) 
     from table t2 
     where t2.incidence > t.incidence 
     ) as rank 
from table t; 

변수 방법은 조금 까다 롭습니다 테이블을 업데이트하려면 join과 함께 update을 사용하십시오.

update table t join 
     (<either subquery above>) s 
     on t.id = s.id 
    set t.rank = s.rank; 
+0

이것은 야만적 인 노력보다 훨씬 깨끗해 보입니다. 그러나, 나는 그 테이블을 업데이트해야한다고 특별히 언급하지 않았다. 나는 새로운 것을 쓸 수 있다고 생각하지만, 업데이트가 훨씬 더 선호 될 것입니다. –

+0

Gordon - var 예제를 사용하여 업데이트 쿼리를 채울 수 있습니까? 당신은 "위의 하위 쿼리를 사용하십시오"라고 말하지만 두 번째 것은 십자가 조인을 가지고 있으며, 나는 그것이 어디로 가는가를 알지 못한다. - 나는 다른 참조를 찾을 수있다. ... thx – jpmyob