Reputation: 3070
I have a gameplay table with the following fields:
user_id, level, clear_time
There are some N number of levels and the table keeps track of when user crosses a certain level. Now, I need to rank user based on two constraints: level
and clear_time
. As it is obvious, user in higher level stands ahead but when more than one user is in the same level, clear_time
is what decides who is ahead i.e. the one to first clear that level stands ahead. Following is what I tried which is not working the way I want to. Level ordering works fine but clear_time
is messed up.
SELECT
u.*,
@rank := @rank + 1 rank
FROM
( SELECT
t1.user_id user_id,
MAX(t1.level) level,
t1.clear_time clear_time,
t2.username username
FROM
gameplay t1
INNER JOIN
users t2
ON
( t1.user_id = t2.id )
GROUP BY
user_id
ORDER BY
level DESC,
clear_time ASC
) u
JOIN
( SELECT @rank := 0 ) r
I see the problem is MAX(level) doesn't get its corresponding clear_time. I can't get it done.
Analyzing the results, I see the corresponding fields to MAX(t1.level)
value are not selected. How do I accomplish this?
Upvotes: 3
Views: 111
Reputation: 323
It sounds like gameplay
has multiple entries per user_id
. That is: an entry for level x
and for level y
both with the same user_id
and you want to select the row with the highest level and the corresponding value of clear_time
, but MAX
will only select the maximum level in the group, and not the value of clear_time
from the same row.
You can do this with an additional JOIN
on gameplay
. Edit: here's an example I setup:
MariaDB [test]> select * from gameplay;
+---------+---------------------+-------+
| user_id | clear_time | level |
+---------+---------------------+-------+
| 1 | 2014-11-08 11:22:25 | 1 |
| 1 | 2014-11-09 11:22:40 | 2 |
+---------+---------------------+-------+
2 rows in set (0.00 sec)
MariaDB [test]> select * from users;
+----+----------+
| id | username |
+----+----------+
| 1 | foo |
+----+----------+
1 row in set (0.00 sec)
The row we would want to select in this example is level=2
, clear_time=2014-11-09 11:22:40
. Here's my query:
MariaDB [test]> SELECT t1.user_id, t2.username, t1.level, t3.clear_time
FROM
(SELECT user_id, max(level) as level FROM gameplay GROUP BY user_id) as t1
INNER JOIN (users t2, gameplay t3)
ON t1.user_id=t2.id AND t3.level=t1.level AND t3.user_id=t1.user_id;
+---------+----------+-------+---------------------+
| user_id | username | level | clear_time |
+---------+----------+-------+---------------------+
| 1 | foo | 2 | 2014-11-09 11:22:40 |
+---------+----------+-------+---------------------+
1 row in set (0.00 sec)
Upvotes: 1