Michael Rich
Michael Rich

Reputation: 301

XP Leveling System - PHP

Rank Table

Ranking Table

In my class I have stored the ranks -- matching those in the Rank Table -- and correlating minimum scores; RANK as key and MINIMUM_SCORE as value.

When a member's score (XP) is updated (up/down) I want to test that updated score against the below array to determine if their rank needs updating too.

private $scores = array('3' => '12116', '2' => '15146', '1' => '18932',);

Using the updated score, how could I determine the correlating rank from the above array?

Everything is open to scrutiny, this is my first time creating a ranking system so I hope to get it right :)

Upvotes: 0

Views: 386

Answers (1)

Brendan Long
Brendan Long

Reputation: 54242

Ok, so given these tables:

Ranks
+------+-----------+-------------------------+
| RANK | MIN_SCORE |          NAME           |
+------+-----------+-------------------------+
|  1   |     18932 | Editor-in-Chief         |
|  2   |     15146 | Senior Technical Writer |
|  3   |     12116 | Senior Copywriter       |
+------+-----------+-------------------------+

Members
+-----------+-------+
| MEMBER_ID | SCORE |
+-----------+-------+
|     1     | 17722 |
|     2     | 16257 |
|     3     | 12234 |
+-----+-------------+

You can get a member plus their rank using:

SELECT m.MEMBER_ID, r.NAME
FROM Members m INNER JOIN Ranks r
ON m.SCORE > r.MIN_SCORE -- Pick ranks that a user is eligible for
WHERE MEMBER_ID = ?
HAVING MAX(r.MIN_SCORE) -- Pick the rank with the highest score

This allows you remove an entire table, which should make your code easier to maintain. Hopefully your rank table will be so small than it will always be in memory, but an index over both MIN_SCORE and RANK will probably be helpful.

If you determine that this join is a performance problem (please don't do this unless you've measured a performance problem), you can use a similar query to update ranks in the members table, assuming it has a RANK column:

UPDATE Members
SET RANK = (
    SELECT RANK
    FROM Ranks
    WHERE SCORE > MIN_SCORE
    AND MEMBER_ID = MEMBER_ID
    HAVING MAX(MIN_SCORE)
)

Upvotes: 1

Related Questions