Based on the above query, I have a solution for you
SET @rnk=0; SET @rank=0; SET @curscore=0;
SELECT score,userid,rank FROM
(
SELECT AA.*,
(@rnk:=@rnk+1) rnk,
(@rank:=IF(@curscore=score,@rank,@rnk)) rank,
(@curscore:=score) newscore
FROM
(
SELECT
userid,
floor(sum(ans = word) / count(id) * 100) as score
FROM fb_asl.quiz
WHERE
DATE(`time`) BETWEEN
CURDATE() + INTERVAL (-3) DAY AND
AND CURDATE() + INTERVAL (-3) DAY
AND ans IS NOT NULL
GROUP BY userid
) AA ORDER BY score DESC) A;
Let me demonstrate it with some sample data
SAMPLE DATA
use test
DROP TABLE IF EXISTS scores;
CREATE TABLE scores
(
id int not null auto_increment,
score int not null,
primary key (id),
key score (score)
);
INSERT INTO scores (score) VALUES
(50),(40),(75),(80),(55),
(40),(30),(80),(70),(45),
(40),(30),(65),(70),(45),
(55),(45),(83),(85),(60);
SAMPLE DATA LOADED
mysql> DROP TABLE IF EXISTS scores;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE scores
-> (
-> id int not null auto_increment,
-> score int not null,
-> primary key (id),
-> key score (score)
-> );
Query OK, 0 rows affected (0.06 sec)
mysql> INSERT INTO scores (score) VALUES
-> (50),(40),(75),(80),(55),
-> (40),(30),(80),(70),(45),
-> (40),(30),(65),(70),(45),
-> (55),(45),(83),(85),(60);
Query OK, 20 rows affected (0.02 sec)
Records: 20 Duplicates: 0 Warnings: 0
mysql>
WHAT SAMPLE DATA LOOKS LIKE
mysql> SELECT * FROM scores;
+----+-------+
| id | score |
+----+-------+
| 1 | 50 |
| 2 | 40 |
| 3 | 75 |
| 4 | 80 |
| 5 | 55 |
| 6 | 40 |
| 7 | 30 |
| 8 | 80 |
| 9 | 70 |
| 10 | 45 |
| 11 | 40 |
| 12 | 30 |
| 13 | 65 |
| 14 | 70 |
| 15 | 45 |
| 16 | 55 |
| 17 | 45 |
| 18 | 83 |
| 19 | 85 |
| 20 | 60 |
+----+-------+
20 rows in set (0.00 sec)
mysql>
MY SOLUTION AGAINST THE SAMPLE DATA
SET @rnk=0; SET @rank=0; SET @curscore=0;
SELECT score,ID,rank FROM
(
SELECT AA.*,BB.ID,
(@rnk:=@rnk+1) rnk,
(@rank:=IF(@curscore=score,@rank,@rnk)) rank,
(@curscore:=score) newscore
FROM
(
SELECT * FROM
(SELECT COUNT(1) scorecount,score
FROM scores GROUP BY score
) AAA
ORDER BY score DESC
) AA LEFT JOIN scores BB USING (score)) A;
MY SOLUTION EXECUTED AGAINST THE SAMPLE DATA
mysql> SELECT score,ID,rank FROM
-> (
-> SELECT AA.*,BB.ID,
-> (@rnk:=@rnk+1) rnk,
-> (@rank:=IF(@curscore=score,@rank,@rnk)) rank,
-> (@curscore:=score) newscore
-> FROM
-> (
-> SELECT * FROM
-> (SELECT COUNT(1) scorecount,score
-> FROM scores GROUP BY score
-> ) AAA
-> ORDER BY score DESC
-> ) AA LEFT JOIN scores BB USING (score)) A;
+-------+------+------+
| score | ID | rank |
+-------+------+------+
| 85 | 19 | 1 |
| 83 | 18 | 2 |
| 80 | 4 | 3 |
| 80 | 8 | 3 |
| 75 | 3 | 5 |
| 70 | 9 | 6 |
| 70 | 14 | 6 |
| 65 | 13 | 8 |
| 60 | 20 | 9 |
| 55 | 5 | 10 |
| 55 | 16 | 10 |
| 50 | 1 | 12 |
| 45 | 10 | 13 |
| 45 | 15 | 13 |
| 45 | 17 | 13 |
| 40 | 2 | 16 |
| 40 | 6 | 16 |
| 40 | 11 | 16 |
| 30 | 7 | 19 |
| 30 | 12 | 19 |
+-------+------+------+
20 rows in set (0.00 sec)
Give it a Try !!!
93, 79, 79, 66be ranked? Should it be a)1, 2, 3, 4, b)1, 2, 2, 4, or c)1, 2, 2, 3? If a), how should the query determine whichuseridmust be assigned which ranking in case of ties? – Andriy M Jun 03 '13 at 11:57scoreexpression a little:floor(avg(100 * (ans = word))) as score. – Andriy M Jun 03 '13 at 12:02