MySQL rank query. Get the position of a specific member - mysql

I have the following table on my DataBase:
TimeRank(user-id, name, time)
I would like to order the table by time and get the position of an specific ID on the table, for example:
The user nÂș 68 is on the 3rd position.
I only need to do a query that returns the position of the user.
MySQL don't have the function row_number, so I don't know how to do it.

SELECT x.user-id,
x.name,
x.time,
x.position
FROM (SELECT t.user-id,
t.name,
t.time,
#rownum := #rownum + 1 AS position
FROM TABLE TimeRank t
JOIN (SELECT #rownum := 0) r
ORDER BY t.time) x
WHERE x.user-id = 123
Alternative:
SELECT user-id,
(SELECT COUNT(*) FROM TimeRank WHERE time <= (SELECT time FROM TimeRank WHERE user-id = 123)) AS position,
time,
name
FROM TimeRank
WHERE user-id = 123

You can generate a position column with a variable
set #pos=0;
select pos,user_id
from (select #pos:=#pos+1 pos,user_id from TimeRank order by time) s
where user_id=68;
If indexing is a concern, you can add a column to your table and update it with
set #pos=0;
update TimeRank set position=(#pos:=#pos+1) order by time;

Related

MySQL - Percentile calculation and update it in other column in the same table

I have a table in MySQL (phpMYAdmin) with the following columns
I am trying to determine the percentile for each row and update that value in the G1Ptile column. G1Ptile column is the percentile calculation based on G1%. I am using the following based on John Woo's answer given here
SELECT `G1%`,
(1-ranks/totals)*100 Percentile FROM (
SELECT distinct `G1%`,
#rank:=#rank + 1 ranks,
(SELECT COUNT(*) FROM PCount) totals
FROM PCount a,
(SELECT #rank:=0) s
ORDER BY `G1%` DESC ) s;
and get the following output
The output is in a select statement, I want to be able to update it to the G1Ptile column in my table, however I am unable to update it using
UPDATE `PCount` SET `G1Ptile`= --(All of the select query mentioned above)
Can you please help with modifying the query/suggest an alternative so that I can use the percentile values obtained using the above query and update it into G1Ptile in the same table. One more problem I have is that there are two 20% values in G1%, however the percentile assigned to one is 20 and other is 30. I want both of them to be 20 and the next row in the series to be 30.
I would write your calculation as:
SELECT `G1%`,
(1 - ranks / totals) * 100 as Percentile
FROM (SELECT `G1%`,
(#rank := #rank + 1) ranks,
(SELECT COUNT(*) FROM PCount) as totals
FROM (SELECT DISTINCT `G1%`
FROM PCount
ORDER BY `G1%` DESC
) p CROSS JOIN
(SELECT COUNT(*) as totals, #rank := 0
FROM Pcount
) params
) p;
I made certain changes more consistent with how MySQL processes variables. In particular, the SELECT DISTINCT and ORDER BY are in a subquery. This is necessary in more recent versions of MySQL (although in the most recent you can use window functions).
This can now be incorporated into an update using JOIN:
UPDATE PCount p JOIN
(SELECT `G1%`,
(1 - ranks / totals) * 100 as Percentile
FROM (SELECT `G1%`,
(#rank := #rank + 1) ranks,
(SELECT COUNT(*) FROM PCount) as totals
FROM (SELECT DISTINCT `G1%`
FROM PCount
ORDER BY `G1%` DESC
) p CROSS JOIN
(SELECT COUNT(*) as totals, #rank := 0
FROM Pcount
) params
) pp
) pp
ON pp.`G1%` = p.`G1%`
SET p.G1Ptile = pp.percentile;

Mysql query to get the row position in a table

I have table with id (store user id) and score in different match. I want what is the position of a user.
So for i try this sql fiddle;
in this I am getting all the row but I need only user having id 3 and it position in the table.
like this:
Score Postion
26 3
Even i try to do like this but no success
MySql: Find row number of specific record
With MySQL, how can I generate a column containing the record index in a table?
I got the answer: http://sqlfiddle.com/#!2/b787a/2
select * from (
select T.*,(#rownum := #rownum + 1) as rownum from (
select sum(score) as S,id from mytable group by id order by S desc ) as T
JOIN (SELECT #rownum := 0) r
) as w where id = 3
Updated sqlfiddle and above query. Now it is working perfectly.
I think this should do the trick:
SELECT totalScore, rownum FROM (
SELECT id,sum(score) AS totalScore,(#rownum := #rownum + 1) AS rownum
FROM mytable
JOIN (SELECT #rownum := 0) r
group by id) result
WHERE result.ID = 3;
just add a where clause
select x.id,x.sum,x.rownum
from(
select id,sum(score) as sum,(#rownum := #rownum + 1) as rownum
from mytable
JOIN (SELECT #rownum := 0) r
group by id
) x
where id =3

MySQL position in recordset

I'm ordering a recordset like this:
SELECT * FROM leaderboards ORDER BY time ASC, percent DESC
Say I have the id of the record which relates to you, how can I find out what position it is in the recordset, as ordered above?
I understand if it was just ordered by say 'time' I could
SELECT count from table where time < your_id
But having 2 ORDER BYs has confused me.
You can use a variable to assign a counter:
SELECT *, #ctr := #ctr + 1 AS RowNumber
FROM leaderboards, (SELECT #ctr := 0) c
ORDER BY time ASC, percent DESC
Does this do what you want?
SELECT count(*)
FROM leaderboards lb cross join
(select * from leaderboards where id = MYID) theone
WHERE lb.time < theone.time or
(lb.time = theone.time and lb.percent >= theone.percent);
This assumes that there are no duplicates for time, percent.

MySQL increment user variable when value changes

I have a table consisting of groups of, for example, five rows each. Each row in each group possesses a date value unique to that group.
What I want to do in my query, is go through the table, and increment a user variable (#count) when this date value changes. That's to say, #count should equal the group count, rather than the row count.
My current query looks like this, in case you're wondering:
SELECT #row := #row +1 AS rownum, date
FROM ( SELECT #row := 0 ) r, stats
Thanks a lot.
What about something like this?
SELECT
(CASE WHEN #date <> date THEN #row := #row +1 ELSE #row END) AS rownum,
#date:= date,
date
FROM ( SELECT #row := 0, #date := NOW() ) r, stats
You don't need a user variable to answer the query that you are doing. Is there a reason you want to use the user variable (for example, to emulate a ranking function?)
If not:
-- how many groups are there?
select count(distinct date) distinct_groups from table;
-- each group and count of rows in the group
select date, count(*) from table group by date;
-- if you want the Nth row from each group, assuming you have an auto_increment called id:
select *
from table
join ( select date, max(id) id
from table
group by date
) sq
on table.id = sq.id

Rank in MySQL table

I have a MySQL table called "MyTable" and it basically lists usernames and points (two columns, name and points). I want to say something like "what is joe1928's rank?", which of course is based off his points. How could I do this in MySQL without having to download all that data and sort it and determine the rank myself?
The person with the highest number of points would be ranked 1.
Try getting the number of people with a higher score than your user:
select count(*) from MyTable where score > (select score from MyTable where user = 'Joe');
That will return 0 for the top user.
This page seems to describe and solve your problem.
Notes from that page:
SET #rownum := 0;
SELECT rank, correct FROM (
SELECT #rownum := #rownum + 1 AS rank, correct, uid
FROM quiz_user ORDER BY correct DESC
) as result WHERE uid=xxxxxxxx
SELECT #r AS Rank
FROM MyTable u, (SELECT #r := 0)
WHERE (#r := #r + 1) * (u.Username = 'joe1928')
ORDER BY u.Score DESC
LIMIT 1
select * from [TABLENAME] where [USERNAME] = blah order by [POINTS] desc limit 1;
Based on the link posted by #Dave your query will look like something below:
select Rank,name from
(select #rownum:=#rownum+1 AS 'Rank', p.name
from calls p, (select #rownum:=0) r
order by p.points desc) as rankResults
where name = 'joe';
This is from another stack overflow page, seems to solve your problem.
SELECT uo.*,
(
SELECT COUNT(*)
FROM users ui
WHERE (ui.points, ui.id) >= (uo.points, uo.id)
) AS rank
FROM users uo
WHERE id = #id