简体   繁体   中英

Ranking - Select corresponding column values to a MAX(column) value

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 ie 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?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM