The following solution uses a stored procedure to work out a user's rank based on a simple ranking system which you could replace with your own more complex one.
call get_user_rank(<user_id>)
I've added another stored procedure which lists the top ten ranks and flags whether the user_id passed in is included in the top ten as I remember that being a requirement from another question of yours.
call list_top_ten_ranks(<user_id>)
Testing (call these sprocs from your php)
select count(*) from users;
count(*)
========
250000
call get_user_rank(54193);
-- 0:00:00.300: Query OK
call get_user_rank(1);
-- 0:00:00.291: Query OK
call list_top_ten_ranks(54193);
-- 0:00:00.208: Query OK
call list_top_ten_ranks(1);
-- 0:00:00.215: Query OK
PHP
$result = $conn->query(sprintf("call get_user_rank(%d)", 1));
$row = $result->fetch_assoc();
$result->close();
echo sprintf("user = %s rank = %s points = %s<br/>",
$row["user_id"],$row["rank"],$row["points"]);
$conn->close();
Hope some of this proves useful.
Script
-- TABLES
drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
points smallint unsigned not null default 0
)
engine=innodb;
-- PROCEDURES
drop procedure if exists get_user_rank;
delimiter #
create procedure get_user_rank
(
p_user_id int unsigned
)
proc_main:begin
-- replace this simple ranking method by your own
set @rank = 0;
create temporary table tmp engine=memory
select
@rank:=@rank+1 as rank,
u.user_id,
u.points
from
users u
order by
u.points desc, u.user_id;
select * from tmp where user_id = p_user_id;
drop temporary table if exists tmp;
end proc_main #
delimiter ;
drop procedure if exists list_top_ten_ranks;
delimiter #
create procedure list_top_ten_ranks
(
p_user_id int unsigned
)
proc_main:begin
-- replace this simple ranking method by your own
set @rank = 0;
set @in_top_ten = 0;
create temporary table tmp engine=memory
select
@rank:=@rank+1 as rank,
u.user_id,
u.points
from
users u
order by
u.points desc, u.user_id
limit 10;
if exists (select 1 from tmp where user_id = p_user_id) then
set @in_top_ten = 1;
end if;
select tmp.*, @in_top_ten as in_top_ten from tmp order by tmp.rank;
drop temporary table if exists tmp;
end proc_main #
delimiter ;