Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>One option is to use a ranking variable, such as the following:</p> <pre><code>UPDATE player JOIN (SELECT p.playerID, @curRank := @curRank + 1 AS rank FROM player p JOIN (SELECT @curRank := 0) r ORDER BY p.points DESC ) ranks ON (ranks.playerID = player.playerID) SET player.rank = ranks.rank; </code></pre> <p>The <code>JOIN (SELECT @curRank := 0)</code> part allows the variable initialization without requiring a separate <code>SET</code> command.</p> <p>Further reading on this topic:</p> <ul> <li><a href="http://code.openark.org/blog/mysql/sql-ranking-without-self-join" rel="nofollow noreferrer">SQL: Ranking without self join</a></li> <li><a href="https://stackoverflow.com/questions/2563918/create-a-cumulative-sum-column-in-mysql/2563940#2563940">Stack Overflow: Create a Cumulative Sum Column in MySQL</a></li> </ul> <hr> <p>Test Case:</p> <pre><code>CREATE TABLE player ( playerID int, points int, rank int ); INSERT INTO player VALUES (1, 150, NULL); INSERT INTO player VALUES (2, 100, NULL); INSERT INTO player VALUES (3, 250, NULL); INSERT INTO player VALUES (4, 200, NULL); INSERT INTO player VALUES (5, 175, NULL); UPDATE player JOIN (SELECT p.playerID, @curRank := @curRank + 1 AS rank FROM player p JOIN (SELECT @curRank := 0) r ORDER BY p.points DESC ) ranks ON (ranks.playerID = player.playerID) SET player.rank = ranks.rank; </code></pre> <p>Result:</p> <pre><code>SELECT * FROM player ORDER BY rank; +----------+--------+------+ | playerID | points | rank | +----------+--------+------+ | 3 | 250 | 1 | | 4 | 200 | 2 | | 5 | 175 | 3 | | 1 | 150 | 4 | | 2 | 100 | 5 | +----------+--------+------+ 5 rows in set (0.00 sec) </code></pre> <hr> <p><strong>UPDATE:</strong> Just noticed the that you require ties to share the same rank. This is a bit tricky, but can be solved with even more variables:</p> <pre><code>UPDATE player JOIN (SELECT p.playerID, IF(@lastPoint &lt;&gt; p.points, @curRank := @curRank + 1, @curRank) AS rank, @lastPoint := p.points FROM player p JOIN (SELECT @curRank := 0, @lastPoint := 0) r ORDER BY p.points DESC ) ranks ON (ranks.playerID = player.playerID) SET player.rank = ranks.rank; </code></pre> <p>For a test case, let's add another player with 175 points:</p> <pre><code>INSERT INTO player VALUES (6, 175, NULL); </code></pre> <p>Result:</p> <pre><code>SELECT * FROM player ORDER BY rank; +----------+--------+------+ | playerID | points | rank | +----------+--------+------+ | 3 | 250 | 1 | | 4 | 200 | 2 | | 5 | 175 | 3 | | 6 | 175 | 3 | | 1 | 150 | 4 | | 2 | 100 | 5 | +----------+--------+------+ 6 rows in set (0.00 sec) </code></pre> <p>And if you require the rank to skip a place in case of a tie, you can add another <code>IF</code> condition:</p> <pre><code>UPDATE player JOIN (SELECT p.playerID, IF(@lastPoint &lt;&gt; p.points, @curRank := @curRank + 1, @curRank) AS rank, IF(@lastPoint = p.points, @curRank := @curRank + 1, @curRank), @lastPoint := p.points FROM player p JOIN (SELECT @curRank := 0, @lastPoint := 0) r ORDER BY p.points DESC ) ranks ON (ranks.playerID = player.playerID) SET player.rank = ranks.rank; </code></pre> <p>Result:</p> <pre><code>SELECT * FROM player ORDER BY rank; +----------+--------+------+ | playerID | points | rank | +----------+--------+------+ | 3 | 250 | 1 | | 4 | 200 | 2 | | 5 | 175 | 3 | | 6 | 175 | 3 | | 1 | 150 | 5 | | 2 | 100 | 6 | +----------+--------+------+ 6 rows in set (0.00 sec) </code></pre> <p>Note: Please consider that the queries I am suggesting could be simplified further.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload