Basically what you're doing here is counting how many users have an atacs
greater than or equal to $userid
's atacs
. Problems with this:
- Terribly inefficient. Note the database retrieves and sends to your
while loop an entry for every user, even those who have an
atacs
less than the $userid
. All but one of these while loop iterations
does nothing by design. Lots of wasted time sending data from the
database to PHP, which doesn't even use it.
- Pulls way more data back
than is necessary. You end up with every row for every user in
your entire
users
table - but your result is just a scalar number
( how many users with > score ).
- Actually gives you wrong results
in the case that your score is tied with others'. In this case some
users with the same score may be counted as "above" the user, others
as "below the users".
Databases are good at iterating over data; it's
all "locally" accessible and the database engine can make many
optimizations if you can describe in SQL what you are trying to
accomplish. So instead of doing it that way, why not just do
everything in the database?
set @user_atacs = ( select atacs from users where id = 12 );
select count(*) +1 from users where atacs > @user_atacs;
I've mocked up the table here: http://sqlfiddle.com/#!2/ff9a86/3
This solution essentially just counts the number of users with a higher atacs
than the current user. All users with the same score will get the same rank, and the next rank will be appropriately higher, so it doesn't suffer from any of your method's errors.
As a final note, the most appropriate way to do something like leaderboards is probably to precompute the leaderboard periodically and then use the results to show each user's position in the leaderboards, rather than trying to compute it on the fly for each user. But that's even farther out of scope :)