I want to get ranking number in Laravel - php

I want to get ranking number in Laravel.
DB is here.
id Bigint
name string
point BigInt
.....
I want to get ranking number in point column.
What should I do?
now code is this.
User::where('id', 1)->first();
if I have these datas.
id name score ...
1 AA 10
2 CD 10
3 ER 40
4 DR 5
I want to get ranking number
ex) id 1 => 2 (or3)
ex) id 3 => 1

You can get the rank as below:
User::selectRaw("SELECT id, name, point, FIND_IN_SET( point, (
SELECT GROUP_CONCAT( DISTINCT point ORDER BY point DESC ) FROM
user )
) AS rank
FROM user")
->get()

Try this. Here is the raw query :
SELECT id,name,point,
#curRank := #curRank + 1 AS rank
FROM user u, (SELECT #curRank := 0) r
ORDER BY point;
You can write it in laravel as follows :
DB::select("SELECT id,name,point,
#curRank := #curRank + 1 AS rank
FROM user u, (SELECT #curRank := 0) r
ORDER BY point;");

Related

How to get rank position from MySQL SELECT statement

I'm trying to get the rank value of a MySQL SELECT statement, (MySQL is not something I'm too familiar with).
This query give me the correct results I am looking for in the correct order (by greater number of stats), but I need to get a particular value from the results.
SELECT id, stats,
#curRank := #curRank + 1 AS rank
FROM statistics.web_stats p, (SELECT #curRank := 0) r
ORDER BY stats DESC;
Gives me this expected result:
id,stats,rank
999,291,1
1137,82,2
1084,79,3
1111,60,4
1097,55,5
1094,51,6
1109,50,7
1112,49,8
1154,44,9
1082,36,10
What I need to do it get the rank value of any particular id, for example, in my PHP code, how would I find the rank position of id 1111 (to return the rank value of '4')?
I'm stuck with hoe to further extract values from the results. Do I need to save them somehow, or can I further expand the MySQL query?
Thanks.
You can use any one of the solutions:
You need to use a subquery to maintain rank position.
This will give you a result whose rank is 4:
SELECT *
FROM
(
SELECT id, stats,
#curRank := #curRank + 1 AS rank
FROM statistics.web_stats p, (SELECT #curRank := 0) r
ORDER BY stats DESC
) AS stat
WHERE rank = 4;
You can even use LIMIT OFFSET to query as they are already in order:
SELECT id, stats,
#curRank := #curRank + 1 AS rank
FROM statistics.web_stats p, (SELECT #curRank := 0) r
ORDER BY stats DESC
LIMIT 4, 1

Loop through rows until you find a variable and then count the number of rows

I'm building a rank system, I have many horses and on the horse profiles I want to echo the rank of the horse depending on the amount of wins. 1st, 2nd, 3rd etc.
This is my MySQL table containing the horses, in PHP how would I count the rows to get the rank of the horse?
Here's my table, for instance if I was on "Pauls" profile, how would I echo out that he is in 4th position in the global ranking?
1.
select h.*, #rownum := #rownum + 1 AS rank
from horses h, (SELECT #rownum := 0) r
order by h.first DESC, h.second DESC, h.third DESC
2.
SELECT * FROM
(
select h.*, #rownum := #rownum + 1 AS rank
from horses h, (SELECT #rownum := 0) r
order by h.first DESC, h.second DESC, h.third DESC
) t
WHERE id = 428
Two queries to get position of your search record
set #name='Paul',#nr = 0, #namenr = 0;
select #namenr as nr from
(SELECT #nr:=#nr+1,if(name=#name, #namenr := #nr,#namenr=#namenr),name FROM SOME_TABLE order by first DESC ) subsel where subsel.name = #name;
second query will return one record with nr column which you are looking for.
Depending on your scoring system, this could be the right solution for you:
Say your 'first' means 3 points, 'second' means 2 points and and 'third' means 1 point.
This way you can calculate what horse has the most points based on the total.
Example:
Paul has 2 'first', 0 'second' and 1 'third', scoring him to 7 points.
Fletcher has 2 'first', no 'second' and no 'third', scoring him to 6 points.
Calculate the sum of all the points and order it by that field, DESC.
Example query:
SELECT (`first`*3)+(`second`*2)+(`third`*1) AS `total_score` FROM `horses` ORDER BY `total_score` DESC
Additional 'rank' field
SET #rank=0;
SELECT #rank:=#rank+1 AS `rank`, (`first`*3)+(`second`*2)+(`third`*1) AS `total_score` FROM `horses` ORDER BY `total_score` DESC
With the following query you can have your table, and next to it the rank of each horse:
SELECT *,
#curRank := #curRank + 1 AS rank
FROM (SELECT #curRank := 0) r, horses
order by first desc, second desc, third desc
I am using the (SELECT #curRank := 0) to initialize the curRank within the query
Use Order By on multiple columns according to priority.
$sql = "SELECT
#rownum := #rownum + 1 as row_number
FROM horses
CROSS JOIN (SELECT #rownum := 0) r
WHERE name = "Paul"
ORDER BY
first ASC,
second ASC,
third ASC";
now you can obtain the position value from query for any users.
To get the rank of a particular horse, you need only count the number of records that rank above it; sorting by row constructors is a very concise way of accomplishing this:
SELECT COUNT(*) + 1
FROM horses
WHERE (first, second, third)
> (SELECT first, second, third FROM horses WHERE id = ?)

MySQL query to get best Ranks from one table and UPDATE with results another

I have a Ranking board for the best first 100 blogs for each gender Males and Females.
I have a blogs table:
PRIMARY
blogs_id users_id blogs_score blogs_score_time gender
1 11 2852 2015-09-09 05:21:51 m <-- same score but older date
2 23 2146 2015-09-10 07:31:54 m
3 23 2146 2015-09-10 07:32:26 m
4 23 2852 2015-09-10 04:42:15 m <-- same score but newer date
5 51 1793 2015-09-11 08:15:55 f
6 88 2947 2015-09-11 09:33:18 f
I have a users table:
PRIMARY
id best_rank gender
11 0 m
23 0 m
51 0 f
88 0 f
I need to COUNT best ranks (using MAX(blogs_score) and MAX(blogs_score_time)) for each user from Blogs table and INSERT/UPDATE the Users table with the best ranks for the first 100 users of each gender with highest ranks, so the result should be:
PRIMARY
id best_rank gender
11 2 m
23 1 m
51 2 f
88 1 f
Where user id 11 has best rank of 2 because user id 11 has same score with user 23 but older date than user 23. Where user 51 has rank 2 because of Female's group. I have added column blogs_score_time to prevent tie ranking. And the date 2015-09-10 means September 10.
The final idea is to show the Rank position in user's profile and once someone voted (blogs_score changes in the blogs table), the best_rank column in the users table must be updated with the new ranks recalculation for ALL 100 users who has the best ranks in particular gender group.
How to adapt and fix this (not working) query to my needs?
$sql->query("UPDATE users
JOIN (SELECT b.users_id,
#curRank := #curRank + 1 AS rank,
MAX(blogs_score), MAX(blogs_score_time)
FROM blogs b
JOIN (SELECT #curRank := 0) r
ORDER BY b.blogs_score DESC, p.blogs_score_time DESC LIMIT 100
) ranks ON (ranks.users_id = users.id)
SET users.best_rank = ranks.rank");
Or how to adapt and fix this (not working) query
$sql->query("INSERT INTO users (best_rank, id)
SELECT #rank := #rank + 1 AS rank, b.users_id
FROM blogs b
LEFT JOIN users u ON b.users_id = u.id
GROUP BY b.users_id, b.blogs_score, b.blogs_score_time, b.gender
ORDER BY b.blogs_score DESC, b.blogs_score_time DESC
ON DUPLICATE KEY UPDATE best_rank = VALUES(rank)");
Please help me with the query to solve it. I didn't find any similar solution on stackoverflow and it seems very complicated for me to write such a query alone.
Thanks a lot in advance!
UPDATE users u, (
SELECT
(
CASE gender
WHEN #curType
THEN #curRow := #curRow + 1
ELSE #curRow := 1 AND #curType := gender END
) + 1 AS rank, users_id, blogs_score, blogs_score_time, gender
FROM blogs,
(SELECT #curRow := 0, #curType := '') r
ORDER BY gender, blogs_score DESC, blogs_score_time DESC
) r1
SET u.best_rank = r1.rank
WHERE
u.id = r1.users_id
It does 2 works:
inner select query generates rank as per gender, score and time
updates user table with respective rank.
I think you should add the a GROUP BY clause this way before ORDER BY
$sql->query("UPDATE users
JOIN (SELECT b.users_id,
#curRank := #curRank + 1 AS rank,
MAX(b.blogs_score), MAX(b.blogs_score_time )
FROM blogs b
JOIN (SELECT #curRank := 0) r
GROUP BY b.user_id, rank
ORDER BY b.blogs_score DESC, p.blogs_score_time DESC LIMIT 100
) ranks ON (ranks.users_id = users.id)
SET users.best_rank = ranks.rank");

Ranking mysql and query for one people

I use this script for my ranking. But I'm not good in MYSQL so maybe someone can help me to change this script to add to this variable:
WHERE id = '$id'
This is what i use:
SELECT id,punkty,
#curRank := #curRank + 1 AS rank
FROM users p, (SELECT #curRank := 0) r
ORDER BY punkty DESC;
I dont know how I can change this script to check one id ? (where id = '$id')
As from comments what i understand the rank given by your query against each user,now you want to know the rank for a given user. You can get the desired rank for the given user's id by doing a sub select
SELECT * FROM (
SELECT id,punkty,
#curRank := #curRank + 1 AS rank
FROM users p, (SELECT #curRank := 0) r
ORDER BY punkty DESC
) t
WHERE id='6';
In below demo if you see the second result set,it shows all the users with their rank and the first query is for one user with id = 6 and his rank is 4 according to the result set of second query
Demo

Mysql Rank of more than one column of one user

How do I go about finding the rank of let's say three stats for one user based on everyone elses stats in one query?
Like
User -> Alan
Level -> 25 (Rank 3)
Wins -> 347 (Rank 1)
Losses -> 2 (Rank 145)
This is what I have
function get_rank($what,$user) {
$v = mysql_query("
SELECT username, #curRank := #curRank + 1 AS rank FROM `users`,
(SELECT #curRank := 0) r
WHERE id = '".$user."' ORDER BY `".$what."`");
$a = mysql_fetch_array($v);
return $v['rank'];
}
It never works.
Table Structure
Id Username level wins losses
1 Alan 25 347 2
2 Joe 34 100 4
3 Sam 12 600 12
Thanks.
SELECT * FROM
(SELECT m.name,rank_level,rank_win ,rank_loss
FROM
(SELECT #rank := #rank + 1 AS rank_level,name,id FROM users ORDER BY level DESC) m
inner join (SELECT #rankw := #rankw + 1 AS rank_win,name,id
FROM users ORDER BY win DESC) w on m.id=w.id
inner join (SELECT #rankl := #rankl + 1 AS rank_loss,name,id
FROM users ORDER BY loss DESC) l on m.id=l.id
, (SELECT #rank := 0) m2,(SELECT #rankw := 0) w2,(SELECT #rankl := 0) l2
) k
WHERE k.name= 'Alan';
SQL FIDDLE HERE

Categories