選項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;
嗨,感謝您的快速回復。 選項1:Postreg是一個選項,我沒有在我自己的服務器上運行。選項2:確實很慢,但那沒關係。不幸的是,我必須排名3分,而不只是一個。所以我需要單獨的排名,這可能嗎? 選項3:與選項2相同 – Tieme 2011-05-14 19:01:23
是的,您需要使用第三個查詢3次並在user_id上加入它們,並使用不同的@rownum變量。 – peufeu 2011-05-14 20:32:35
好吧,這是一個很難!已經嘗試了一段時間,但現在還沒有成功,正在努力! – Tieme 2011-05-15 08:32:42