How to make a table with the result of calculated rankings? - php

I'd like to make new table with the result of calculated rankings from a table. I work with PHP and MySQL.
I got some codes from googling and it works on the screen.
Select User_Id, Score, #rank := #rank + 1 as Ranking
from Rankings, (select #rank := 0) XX
order by Score desc
I'd like to know how to create new table with these data, so that I can see the rankings anytime I want.
And I wonder if this code is good for big data (lots of records).
Can anyone help this beginner? Thanks in advance for any help.

1: CREATE TABLE ... SELECT Syntax: You can create one table from another by adding a SELECT statement at the end of the CREATE TABLE statement.
CREATE TABLE new_table_name AS
SELECT User_Id, Score, #rank := #rank + 1 AS Ranking
FROM Rankings, (SELECT #rank := 0) XX
ORDER BY Score DESC;
Note: This will auto-detect column datatype and column names based on the select query and sometimes they are not proper.
To create desired column names and their data types, you can mention the same in CREATE TABLE clause.
CREATE TABLE new_table_name (user_id INT NOT NULL, rank INT)
SELECT User_Id, Score, #rank := #rank + 1 AS Ranking
FROM Rankings, (SELECT #rank := 0) XX
ORDER BY Score DESC;
2: INSERT ... SELECT Syntax: This will be used to store data of a select statement in the existing table.
INSERT INTO existing_table_name (user_id, rank)
SELECT User_Id, Score, #rank := #rank + 1 AS Ranking
FROM Rankings, (SELECT #rank := 0) XX
ORDER BY Score DESC;

According to this and this, you can use the CREATE TABLE ... SELECT syntax.
CREATE TABLE `UserRankings` AS SELECT User_Id, Score, #rank := #rank + 1 AS Ranking
FROM Rankings, (SELECT #rank := 0) XX
ORDER BY Score DESC

You can create a new table based on select query Data by using the following syntax
CREATE TABLE new_tbl [AS] select query;
Based on your query
Create table Tablename AS Select User_Id, Score, #rank := #rank + 1 as Ranking
from Rankings, (select #rank := 0) XX
order by Score desc
For more information refer https://dev.mysql.com/doc/refman/5.6/en/create-table-select.html

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

Mysql query from ordered query

I've done some research and ended up with this query.
SET #row_num = 0;
SELECT
#row_num := #row_num + 1 as row_number
,id
,maxPoints
FROM users
ORDER BY maxPoints
...that gives me indexes of table ordered by maxPoints. And now comes the query for smarter people...How do I get the row_number WHERE id = $i AND ... (other parameters) from this result.
Is it possible to do it by one composed query or do I need to split those queries on php side? I'm not able to put it up syntactically.
Just put it in a subquery and select from that
select row_number
from
(
SELECT id, #row_num := #row_num + 1 as row_number
FROM users
CROSS JOIN (select #row_num := 0) r
ORDER BY maxPoints
) tmp
where id = $id
BTW you can init the #row_num variable with a subquery too, like I did in my query

PHP Ranking and updating all database rows

Trying to rank the rows in my table and then update a field in each row with its rank number. The ranking will be based on a field with a points value.
The database structure is as follows:
Table name: blogs
fields: ID, buildpointsNow, build_rank
I want to run a cron job that will rank each row depending on its buildpointsNow value and then update its build_rank with that rank number.
So far i have tried:
UPDATE blogs
JOIN (SELECT p.id,
#curRank := #curRank + 1 AS rank
FROM blogs p
JOIN (SELECT #curRank := 0) r
ORDER BY p.buildpointsNow DESC
) ranks ON (ranks.id = blogs.id)
SET blogs.build_rank = blogs.build_rank;
And also:
update blogs cross join
(select #rn := 0) vars
set build_rank = (#rn := #rn + 1);
order by buildpointsNow;
Both of these throw no errors and do update the database rows. However they do not order the builds rank depending on the buildpointsNow field. They instead update each row in its order of creation / its ID.
Any ideas?
blogs need to be ordered by buildpointsNow before adding #curRank:
update blogs
join (
select p.id, #curRank := #curRank + 1 as rank
from (select id from blogs order by buildpointsNow) p
join (select #curRank := 0) r) ranks on ranks.id = blogs.id
set blogs.build_rank = ranks.rank;
Demo
Create a separate table and store ranking order there. You need a column with post_id and one with score. Every time you add/subtract points from score modify that column. And when you need to display the posts in ranking order, just sort that second lighter table table and join the posts heavier table.
Also make sure you index the score column.

Why mysql returns null although data is there?

Check out this:
My SQL query is:
SELECT #rownum := #rownum + 1 AS ID, SKU, SUM(Quantity) FROM orders, (SELECT #rownum := 0) r
WHERE ShipDate BETWEEN 01-05-2013 AND 11-05-2013
GROUP BY SKU
And in my code, I am doing the following:
$sql = "SELECT #rownum := #rownum + 1 AS ID, SKU, SUM(Quantity)
FROM orders, (SELECT #rownum := 0) r
WHERE ShipDate BETWEEN {$from_date } AND {$to_date }
GROUP BY SKU";
I want to select data that falls between two values.
ShipDate is a text field and not a date field. I checked the table, and it holds the data, but MySQL returns null.
Why? What I am doing wrong?
How can I update my PHP code?
This code:
"SELECT #rownum := #rownum + 1 AS ID, SKU, SUM(Quantity)
FROM orders, (SELECT #rownum := 0) r
WHERE STR_TO_DATE(ShipDate,'%d-%m-%Y') BETWEEN {$from_date } AND {$to_date }
GROUP BY SKU";
is not working for me.
Please help me.
Use STR_TO_DATE() to convert the text into a date
SELECT #rownum := #rownum + 1 AS ID,
SKU,
SUM(Quantity)
FROM orders, (SELECT #rownum := 0) r
WHERE STR_TO_DATE(ShipDate,'%d-%m-%Y') BETWEEN '2013-05-01' AND '2013-05-11'
GROUP BY SKU
and add quotes around the date and rearrange the date to yyyy-mm-dd
As ShipDate is text field so BETWEEN operator is not evaluated correctly in case of Text data so you query fails. Convert your Text data in to Date using STR_TO_DATE()

Get rank of player from mysql query

I found some good answers for this question, but I can't really get them to work.
I wan't to get a players rank from a hiscore table.
id name score
1 John 10
2 Linda 5
3 Emmy 25
I want to pass in a name in the query (Linda) and get her rank (She only have 5 points in the table above), and get her rank (nr 3).
I found a similar question with this answer, but don't understand it:
SELECT uo.*,
(
SELECT COUNT(*)
FROM users ui
WHERE (ui.points, ui.id) >= (uo.points, uo.id)
) AS rank
FROM users uo
WHERE id = #id
Thanks in advance
SELECT (COUNT(*) + 1) AS rank FROM hiscore WHERE score > (SELECT score FROM hiscore WHERE name = 'Linda')
Try this query -
SELECT name, score, rank FROM
(SELECT *, #r:=#r + 1 rank FROM table_name ORDER BY score DESC) t1,
(SELECT #r:=0) t2
WHERE name = 'Linda'
SET #rownum := 0;
SELECT rank, name, score
FROM
(SELECT #rownum := #rownum + 1 AS rank, name, score
FROM players
ORDER BY score DESC)

Categories