Get user rank with MySQL
SELECT
COUNT(*) AS rank
FROM users
WHERE Points>=(SELECT Points FROM users WHERE User_id=4)
Updated with some more useful stuff:
SELECT
user_id,
points,
(SELECT COUNT(*)+1 FROM users WHERE Points>x.points) AS rank_upper,
(SELECT COUNT(*) FROM users WHERE Points>=x.points) AS rank_lower
FROM
`users` x
WHERE x.user_id = 4
which includes the range of ranks user is at. So for example if the scores for first five places are 5 4 3 3 3, the result would be:
id points rank_upper rank_lower
id 5 1 1
id 4 2 2
id 3 3 5
id 3 3 5
id 3 3 5
MySQL to find rank of specific user if multiple users have same values
You can use ROW_NUMBER()
window function such as
SELECT q.rnk
FROM ( SELECT ROW_NUMBER() OVER (ORDER BY `count` DESC, `id`) AS rnk,
r.*
FROM `records` AS r
WHERE `type` = 1 ) AS q
WHERE q.`sub_id` = 'ali' -- 'faisal'
Demo
most probably you're currently using DENSE_RANK()
or RANK()
functions(including ORDER BY count DESC
) those may yield equal rank values unlike to ROW_NUMBER()
How to get one user's rank from mysql db?
SET @rank_cnt := 0;
SET @prev_score := NULL;
SELECT * FROM (
SELECT b.id
, b.name
, @rank_cnt := IF(@prev_score = b.score,@rank_cnt,@rank_cnt+1) AS rank
, @prev_score := b.score AS score
FROM BBR b
ORDER BY b.score DESC, b.id DESC
) AS subQ
WHERE subQ.name = "sim";
If you are using the same connection, you shouldn't need that bogus "JOIN" to initialize your session variables.
How to get the rank of a specific user with MySql
I will be glad for the day when MySQL 5x is fully supplanted by MySQL8+ and there are for real Window Functions in MySQL. Until that day, though, for MySQL 5x / MariaDB <10.2, you can use something like:
SELECT username
, progress_percent
, gold_count
, @uRank := @uRank + 1 AS theRank
FROM mytable t, ( SELECT @uRank := 0 ) r
ORDER BY progress_percent DESC, gold_count DESC, modify_date DESC
EDIT: Apparently Window Functions weren't added to MariaDB until 10.2. :-S
If you were using MySQL 8+ or MariaDB 10.2+, you could just use a Rank Window Function:
SELECT username
, progress_percent
, gold_count
, ROW_NUMBER() OVER (ORDER BY progress_percent DESC, gold_count DESC, modify_date DESC ) AS theRank
FROM mytable t
ORDER BY theRank
EDIT 2:
For a specific user, just put the above queries into a subquery and SELECT
the Rank
you want.
SELECT s1.username, s1.progress_percent, s1.gold_count
FROM (
[above query here]
) s1
WHERE s1.theRank = <theRankYouWant>
or
WHERE s1.username = <theUsernameYouWant>
get users before and after a specific user with its rank
You already gave the answer inside your question.
It would be (Sql Server style)
DECLARE @myRank int
SELECT @myRank = rank() OVER (Order BY points DESC) FROM client WHERE id = x;
Select *, rank() OVER (Order BY points DESC) as rank
FROM client
HAVING rank between (@myRank - 5) and (@myRank +5);
If you want it in pure SQL, you'll have to work a little extra, but it's the same idea (just with sub-queries).
MySQL, Get users rank
SELECT uo.*,
(
SELECT COUNT(*)
FROM users ui
WHERE (ui.points, ui.id) >= (uo.points, uo.id)
) AS rank
FROM users uo
WHERE id = @id
Dense rank:
SELECT uo.*,
(
SELECT COUNT(DISTINCT ui.points)
FROM users ui
WHERE ui.points >= uo.points
) AS rank
FROM users uo
WHERE id = @id
MySQL find user rank for each category
First, you need to get the total points per category. Then you need to enumerate them. In MySQL this is most easily done with variables:
SELECT user_id, category_id, points,
(@rn := if(@cat = category_id, @rn + 1,
if(@cat := category_id, 1, 1)
)
) as rank
FROM (SELECT u.user_id, u.category_id, SUM(u.points) as points
FROM users u
GROUP BY u.user_id, u.category_id
) g cross join
(SELEct @user := -1, @cat := -1, @rn := 0) vars
ORDER BY category_id, points desc;
SELECT user ranking on MySQL by an offset
In MySQL 8.0, just use window functions, as demonstrated by Gordon Linoff.
In earlier versions, you basically need a subquery to do what you want. I would recommend:
SELECT *
FROM (
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM (SELECT * FROM usuarios ORDER BY xp DESC) u
CROSS JOIN (SELECT @curRank := 0) r
ORDER BY xp DESC
) t
ORDER BY xp DESC
LIMIT 10, 10;
The subquery ranks all users first, then you can safely filter in the outer query. Note that the query pre-orders the table by xp
in a subquery first: this is safer (user variables are tricky in MySQL).
Actually, you don't even needLIMIT
in the outer query; you can use a WHERE
clause instead:
SELECT *
FROM (
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM (SELECT * FROM usuarios ORDER BY xp DESC) u
CROSS JOIN (SELECT @curRank := 0) r
ORDER BY xp DESC
) t
WHERE rank BETWEEN 11 AND 20
ORDER BY rank
Related Topics
Error: Functions in Index Expression Must Be Marked Immutable in Postgres
Why Do We Need Group by with Aggregate Functions
How to Do an Inner Join on Row Number in SQL Server
SQL Server 2005 Row_Number() Without Order By
Linux Python3 - Can't Open Lib 'SQL Server'
How to Compare Two SQLite Databases on Linux
How to Read the Contents of an .SQL File into an R Script to Run a Query
Rodbc Temporary Table Issue When Connecting to Ms SQL Server
Pass String Variable in R Script to Use It in SQL Statement
Getting a Rank from Activerecord
How to Turn on Regexp in SQLite3 and Rails 3.1
Representing Ecommerce Products and Variations Cleanly in the Database
Sqlite3 "Forgets" to Use Foreign Keys
SQL Server (Tsql) - How to Exec Statements in Parallel
Query Runs Slow with Date Expression, But Fast with String Literal