2011-05-14 24 views
1

下週末我們將舉行一場半決賽和決賽的三項比賽。只有最好的15名參賽者才能參加半決賽。總決賽只有最佳6人蔘賽。mySQL排名(並提取)

的資格你從0到100的得分爲每個資格

我期待找到一種方法來選擇半決賽的參賽選手。這應該是基於(qualification1的等級)*(qualification2的等級)*(qualification3的排名)

,所以我需要的東西,如:

select id, name, ((.... as RANK_OF_SCORE_1) * (.. as RANK_OF_SCORE_2) * (... as  RANK_OF_SCORE_3)) as qualification_score from participants order by qualification_score desc limit 15 

當然,但這不是有效的MySQL。

此外,如果壽參賽選手具有相同的比分,他們應該都包含在半決賽即使這超過了最大的15

決賽這個問題,我們要選擇最好的6的半決賽比分。如果分數是一樣的,我們希望在資格選擇..

回答

5

選項1:使用的Postgres,支持窗口函數(即RANK()和DENSE_RANK())

SELECT user_id, score, rank() over (order by score desc) from scores; 
Time : 0.0014 s 

選項2:使用自聯接:具有分數X的用戶的排名是(1+分數小於X的用戶的計數(*));這很可能是相當緩慢

CREATE TABLE scores(user_id INT PRIMARY KEY, score INT, KEY(score)); 
INSERT INTO scores SELECT id, rand()*100 FROM serie LIMIT 1000; 

SELECT a.user_id, a.score, 1+count(b.user_id) AS rank 
    FROM scores a 
    LEFT JOIN scores b ON (b.score>a.score) 
    GROUP BY user_id ORDER BY rank; 

+---------+-------+------+ 
| user_id | score | rank | 
+---------+-------+------+ 
|  381 | 100 | 1 | 
|  777 | 100 | 1 | 
|  586 | 100 | 1 | 
|  907 | 100 | 1 | 
|  790 | 100 | 1 | 
|  253 | 99 | 6 | 
|  393 | 99 | 6 | 
|  429 | 99 | 6 | 
|  376 | 99 | 6 | 
|  857 | 99 | 6 | 
|  293 | 99 | 6 | 
|  156 | 99 | 6 | 
|  167 | 98 | 13 | 
|  594 | 98 | 13 | 
|  690 | 98 | 13 | 
|  510 | 98 | 13 | 
|  436 | 98 | 13 | 
|  671 | 98 | 13 | 

time 0.7s 

選項3:

SET @rownum = 0; 
SELECT a.user_id, a.score, b.r FROM 
scores a 
JOIN (
    SELECT score, min(r) AS r FROM (
     SELECT user_id, score, @rownum:[email protected]+1 AS r 
     FROM scores ORDER BY score DESC 
    ) foo GROUP BY score 
) b USING (score) 
ORDER BY r; 

time : 0.0014 s 

編輯

SET @rownum1 = 0; 
SET @rownum2 = 0; 
SET @rownum3 = 0; 

SELECT s.*, s1.r, s2.r, s3.r FROM 
scores s 
JOIN 
(
    SELECT score_1, min(r) AS r FROM (
     SELECT score_1, @rownum1:[email protected]+1 AS r 
     FROM scores ORDER BY score_1 DESC 
    ) foo GROUP BY score_1 
) s1 USING (score_1) JOIN (
    SELECT score_2, min(r) AS r FROM (
     SELECT score_2, @rownum2:[email protected]+1 AS r 
     FROM scores ORDER BY score_2 DESC 
    ) foo GROUP BY score_2 
) s2 USING (score_2) JOIN (
    SELECT score_3, min(r) AS r FROM (
     SELECT score_3, @rownum3:[email protected]+1 AS r 
     FROM scores ORDER BY score_3 DESC 
    ) foo GROUP BY score_3 
) s3 USING (score_3) 
ORDER BY s1.r * s2.r * s3.r; 
+0

嗨,感謝您的快速回復。 選項1:Postreg是一個選項,我沒有在我自己的服務器上運行。選項2:確實很慢,但那沒關係。不幸的是,我必須排名3分,而不只是一個。所以我需要單獨的排名,這可能嗎? 選項3:與選項2相同 – Tieme 2011-05-14 19:01:23

+0

是的,您需要使用第三個查詢3次並在user_id上加入它們,並使用不同的@rownum變量。 – peufeu 2011-05-14 20:32:35

+0

好吧,這是一個很難!已經嘗試了一段時間,但現在還沒有成功,正在努力! – Tieme 2011-05-15 08:32:42