MYSQL position of row by order - php

I have had a look through google results, but can't find a simple answer, I have a table
id, points (and more fields, but they dont affect anything)
How would I go about Getting position of record 24(id) ordered by points DESC?

I'm not sure I've understood your question
select * from table order by points desc limit 23,1

Select Count(*) from (
Select ID from UnNamedTable A where A.points>(Select B.Points from UnNamedTable B where B.ID=24)
)

Are you trying to figure out out what place a user is in based on a points system?
If so then just find how many users have more points than a particular user then add 1.
SELECT COUNT(*) + 1 AS 'position' FROM table WHERE points >
( SELECT points FROM table WHERE id = someIDhere )

You could create a variable to keep track of your row position after sorting. Something like this would work:
select #rownum:=#rownum+1 ‘rank’, p.* from table1 p, (SELECT #rownum:=0) ID order by Points desc limit 10;

Related

Query to get the rank of a user in a database table based on two rows

I am working on an app where users can take online exams and then they need to know their rank on all exams taken in the app.
This is the database table structure:
After taking the exam, I need to get the rank for the specific user (usuario) based on two rows, first row to get the rank must be the bigger (puntuacion) and in case of same (puntuacion) the second row to be taken into account is the smaller (duracion) for an specific exam subject (materia).
I need your help to create the needed query.
You want the results sorted by "puntuacion" and "duracion". That's done with order by
SELECT * FROM your_table ORDER BY puntuacion DESC, duracion ASC
It's not quite clear how you want to sort it, so you may have to switch around ASC with DESC.
If you want to add the row number and have a high enough MariaDB/Mysql-Version (Mysql 8.0) then you can use a window-function: https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html
SELECT
ROW_NUMBER() OVER (ORDER BY puntuacion DESC, duracion ASC) as row,
*
FROM your_table
ORDER BY puntuacion DESC, duracion ASC
Assuming the users are unique (delete DESC if you need to rank by ascending order) :
SELECT * FROM tableName ORDER BY puntuacion DESC, duracion DESC;
Fetch it as an array and get the row with $result[array_search($user)]. Not tested but it should work, let me know.
This is kinda heavy if you have a lot of users (it loads every users every time), but I don't see other solutions.
I have got a working query:
SELECT t.*, #rownum := #rownum + 1 AS rank FROM tb_examenes t, (SELECT #rownum := 0) r WHERE materia = 10 ORDER by puntuacion DESC, duracion ASC
Then I only have to filter for the field I need.

Join multiple tables and order by sum of row

Recently began working on a matchmaking system, where in this system there are 2 tables. One table is for matches and one table is for ranks.
The table for ranks starts off like this
table_ranks:
date
playeruid
rank
table_matches:
date
playeruid
playerpoints
I'm trying to now order the player by their points. However, in order to do this, I have made a query:
SELECT * FROM table_ranks ORDER by rank DESC
But now what I realize, is that I need to add the playerpoints on top of the rank. So basically, I need to add playerpoints to the player's current ranking. So, if I had this for an example row:
table_ranks:
2/20/15
Player1
56
table_matches:
2/27/15
Player1
5
I would need to build a query that takes the 56 of player1, looks for player1 in the matches and anywhere it sees it, it would need to add his 5 points making it a sum of 56. Once this is determined it would ORDER by this value in order to determine who is ranked with what. How do I begin my query? I understand that in order to join the tables, I need to start off like this:
"SELECT table_ranks., table_matches. from table_ranks, table_matches ORDER by RANK..."
Then to finish it,I would have to take the current value of the rank, then grab the specific player it's referring to and take all the matches and add up all the playerpoints to his rank then to determine how to order it by.
Try this:
SELECT r.playeruid, r.date AS rank_date, m.date AS macthes_date,
(r.rank + m.playerpoints) AS total_points
FROM table_ranks r INNER JOIN table_matches m ON r.playeruid = m.playeruid
ORDER BY total_points DESC
This query assumes that playeruid is unique in both tables.
Try the following query. I tested on a similartable structure and it should work
SELECT * , playeruid AS player_id, (
SELECT SUM( playerpoints )
FROM `table_matches`
WHERE playeruid = player_id
) AS points
FROM table_ranks
ORDER BY points DESC

Mysql - How to get a row number after Order by?

Let's say I have a table with the following columns:
p_id
userid
points
Let's say these columns have over 5000 records. So we actually have users with points. Each user has an unique row for their point record. Imagine that every user can get points on the website by clicking somewhere. When they click I update the database with the points they get.
So we have a table with over 5000 records of people who have points, right? Now I would like to order them by their points (descending), so the user with the most point will be at the top of the page if I run a MySQL query.
I could do that by simply running a query like this:
SELECT `p_id` FROM `point_table` ORDER BY `points` DESC
This query would give me all the records in a descending order by points.
Okay, here my problem comes, now (when it is ordered) I would like to display each user which place are they actually. So I'd like to give each user something like this: "You are 623 of 5374 users". The problem is that I cannot specify that "623" number.
I would like to run a query which is order the table by points it should "search" or count the row number, where their records are and than return that value to me.
Can anyone help me how to build a query for this? It would be a really big help. Thank you.
This answer should work for you:
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, p_id FROM point_table ORDER BY points DESC;
Update: You might also want to consider to calculate the rank when updating the points and saving it to an additional column in the same table. That way you can also select a single user and know his rank. It depends on your use cases what makes more sense and performs better.
Update: The final solution we worked out in the comments looked like this:
SELECT
rank, p_id
FROM
(SELECT
#rank:=#rank+1 AS rank, p_id, userid
FROM
point_table, (SELECT #rank := 0) r
ORDER BY points DESC
) t
WHERE userid = intval($sessionuserid);
Row number after order by
SELECT ( #rank:=#rank + 1) AS rank, m.* from
(
SELECT a.p_id, a.userid
FROM (SELECT #rank := 0) r, point_table a
ORDER BY a.points DESC
) m
For some reason the accepted answer doesn't work for me properly - it completely ignores "ORDER BY" statement, sorting by id (primary key)
What I did instead is:
SET #rn=0;
CREATE TEMPORARY TABLE tmp SELECT * FROM point_table ORDER BY points DESC;
SELECT #rn:=#rn+1 AS rank, tmp.* FROM tmp;
Add a new column for position to the table. Run a cron job regularly which gets all the table rows ordered by points and then update the table with the positions in a while loop.

Order results by results from a different table in one query

Is it possible to have something like this in one query,
Count how many likes a certain ID has in image_likes and then order results from images descending by how many likes they have.
SELECT
*
FROM
`images`
ORDER BY
(SELECT COUNT(`id`) FROM `image_likes` WHERE `image_id`=images.`id`) ASC
(I have of course made up field names, but this format should work)
If possible, you might want to change the way the system works so that you can just read the total likes from a field name rather than doing a subselect.
Untested
select imageid, count(imageid) from image_likes
Group by imageid
Order by Count(imageid) desc
select * from (SELECT *,(SELECT COUNT(*) as count from image_likes il WHERE ID = i.ID)
FROM images) tbl ORDER BY COUNT
untested

how to get position rank of specific row using just mysql query?

I have table Users which contains columns: id, name, points, extra_points.
How can I get position rank for specific user, when the rank is sum of points and extra_points?
For all users list rank Im using this query: "SELECT id, (points + extra_points) AS total FROM users ORDER BY total desc"; and the while loop with html ol tag (so there is position number).
But I dont know how to show the rank for a sinlge user (in user profile page)?
Any help will be great.
SELECT users1.id, (users1.points+users1.extra_points) AS total, COUNT(*)+1 AS rank
FROM users users1
INNER JOIN users users2 ON users1.points+users1.extra_points < users2.points+users2.extra_points
WHERE users1.id = $id
Well, for a single user, you'd change the select query so it looks like
"SELECT (points + extra_points) AS total FROM users WHERE id = $id LIMIT 1"
Need to specify which user as a WHERE clause. Also, since you presumably know the id already, don't need to select it, and since it's just one user, don't need the ORDER BY either. And LIMIT 1 will stop it from checking the rest of the rows once it's found it.
this isn't tested, but i hope you can understand whats my idea - simply use a subselect to count all users with more points:
SELECT
id,
(points + extra_points) AS total,
(SELECT COUNT(*) FROM users WHERE (points + extra_points)) >= (u.points + u.extra_points) AS rank
FROM
users u
WHERE
id = ?;
Here's the answer if you have a ClientID and Points column in a table called Client:
<CFQUERY DATASOURCE="YourDatasource" name="YourQueryName">
SELECT ClientID, (Pts) AS total,
(SELECT COUNT(*) FROM Client
WHERE (Pts) >= (u.Pts)) AS rank
FROM Client u
WHERE ClientID = CLIENTID_OF_YOUR_CHOICE_HERE;
</CFQUERY>

Categories