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
Related
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
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
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.
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
I have following PHP code:
$result = mysql_query('
set #num := 0, #type := "";
UPDATE orders INNER JOIN (
SELECT id, user_id, created, row_number
FROM
(
SELECT id, user_id, created,
#num := if(#type = user_id, #num + 1, 1) AS row_number,
#type := user_id AS dummy
FROM orders
WHERE status = "queue" AND type="order"
ORDER BY user_id, created asc
) AS grouped_orders
WHERE grouped_orders.row_number <= 2
) m ON orders.id = m.id
SET orders.status = "process", orders.lock_id = "hash";
');
When I skip $result = mysql_query(' and '); and copy-paste this query to my PHP MyAdmin panel it works - but when I execute it with mysql_query(...) from PHP I get following error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE orders INNER JOIN (
SELECT id, user_id, created, row_number
FROM' at line 2
I tried to do something with brackets, movig up/down and collapsing to one line but it doesnt work...
Unfortunately on server I am working on there is no mysqli.
try multi-query instead of mysql_query since you are executing more that one query
Edit
Try defining your variables in your select due subselects:
UPDATE orders INNER JOIN (
SELECT id, user_id, created, row_number
FROM
(
SELECT id, user_id, created,
#num := if(#type = user_id, #num + 1, 1) AS row_number,
#type := user_id AS dummy
FROM orders
WHERE status = "queue" AND type="order"
ORDER BY user_id, created asc
) AS grouped_orders, (SELECT #num:=0) r, (SELECT #type:="") t
WHERE grouped_orders.row_number <= 2
) m ON orders.id = grouped_orders.id
SET orders.status = "process", orders.lock_id = "hash";
try this:
$result = mysql_query('
set #num := 0, #type := "";
UPDATE orders INNER JOIN (
SELECT id, user_id, created, row_number
FROM
(
SELECT id, user_id, created,
#num := if(#type = user_id, #num + 1, 1) AS row_number,
#type := user_id AS dummy
FROM orders
WHERE status = "queue" AND type="order"
ORDER BY user_id, created asc
) AS grouped_orders
WHERE grouped_orders.row_number <= 2
) m ON orders.id = grouped_orders.id
SET orders.status = "process", orders.lock_id = "hash";
');
the group order is the name of the second table to join
EDIT:
Your query looks to be O.K (at least there is no error), however your problem rely in PHP you are using mysql_query.
"mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier. " (http://php.net/manual/en/function.mysql-query.php)
So you need another way to execute multi queries, or find another solution, try to force to use the mysqli because you'll prevent attacks too and will be able to multi queries....