I'm making an tracking app, and i want to show the user on which place he/she is. For this I thaught of ordering by 'totalkm' desc and then get the row number. The problem is i don`t know how to do this, as i'm fairly new to the Database world.
I tried something like this:
WITH mytable AS {
SET #row_number = 0;
SELECT (#row_number := #row_number +1) AS num, user,totalkm
FROM profile ORDER BY totalkm DESC ; }
SELECT num
FROM mytable WHERE user = "bogdan9832";
But i get the 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 'mytable AS {
SET #row_number = 0' at line 1
From what i understood, there is no support for WITH in mysql. Can someone show me an alternative?
You have to use following query for the same:-
First declare the variable as:-
SET #row_number = 0;
Then use this query:-
SELECT (#row_number:= #row_number + 1) AS ROW_NUMBER, OTHER_COLS
FROM YOUR_TABLE;
SELECT num, user, totalkm
FROM (
SELECT (
#row_number := #row_number +1
) AS num, user, totalkm
FROM profile
ORDER BY totalkm DESC
) AS a
WHERE user = "bogdan9832"
Using sub queries but only a single SQL statement:-
SELECT num
FROM
(
SELECT (#row_number := #row_number +1) AS num, user, totalkm
FROM
(
SELECT banner.*
FROM profile
ORDER BY totalkm DESC
) profile
CROSS JOIN (SELECT #row_number := 0) sub0
) sub0
WHERE user = "bogdan9832"
Related
My task is inserting 3 random datas per ID from another table
and I got a mistake with syntax
set #num := 0, #type := '' ,#stat :='';
INSERT INTO random
as
(
SELECT
*
FROM (
select userID,userNAME, chaID, chaNAME,goal,gender,
#num := if(#type = userID, #num +1,1) as row_number,
#type := userID as dummy,
#stat as status
from userchar
order by userID
) as x where x.row_number <= 3)
I'm going to put this code in event scheduler to insert the new datas in daily
1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near 'INSERT INTO random as ( SELECT * FROM ( select userID,userNAME,
chaID, c' at line 2
thank you so much for every suggestions.
I suspect the problem is trying to run multiple statements at the same time. You can fix this by initializing the variables in the query itself:
INSERT INTO random( . . . )
select u.*
from (select userID, userNAME, chaID, chaNAME, goal, gender,
(#num := if(#u = userID, #num +1,
if(#u := userId, 1, 1)
)
) as row_number,
userID as dummy,
#stat as status
from userchar u cross join
(select #u = '', #num := 0, #stat := '') params
order by userID, rand()
) u
where u.row_number <= 3;
There are several other issues:
When using insert, always list the columns. This is particularly important if you are learning SQL, so you learn good habits.
You should not assign a variable value in one expression and use it in another. MySQL (and MariaDB) do not guarantee the order of evaluation of expressions in a select, so the expressions can be evaluated in either order.
If you want random rows, then use rand(). There is a difference between "indeterminate" and "random".
I am getting error : View's SELECT contains a variable or parameter with the query below.How do I create view for the same.I really appreciate any help.Thanks in Advance.
CREATE VIEW V AS SELECT #rownum := #rownum + 1 AS rank, name, vote
FROM uservotes, (SELECT #rownum := 0) t ORDER BY vote DESC
declare #rownum int
CREATE VIEW V AS SELECT #rownum := #rownum + 1 AS rank, name, vote
FROM uservotes, (SELECT #rownum := 0) t ORDER BY vote DESC
Try like this
CREATE VIEW V AS
(
SELECT (SELECT 1 + COUNT(*) FROM uservotes where votes < T.votes ) AS NUM, name, votes
FROM uservotes T ORDER BY votes DESC
)
Fiddle Demo
You can define a variable in order to get psuedo row number functionality, because MySQL doesn't have any ranking functions:
Can't Use A Variable in a MySQL View
If you do, you'll get the 1351 error, because you can't use a variable in a view due to design. The bug/feature behavior is documented here.
I have a list of players. The players are sorted by points. What I'd like to know is how do I get the ranking number of a CERTAIN player?
This is my code so far (which doesn't work because it seems to have some bugs):
$rank = mysql_query (SET #rank := 0;
SELECT *, #rank := #rank + 1
FROM ava_users
WHERE id = '".$id."'
ORDER BY points DESC);
$rank_res = mysql_fetch_array($rank);
When I try to use my query I get an error message:
mysql_fetch_array() expects parameter 1 to be resource, boolean given in /Users/***/Documents/Arcades/Arc_development/arc_projects/***/arc_dev_website/arc_offline/includes/profile/profile_main.inc.php
$rank = mysql_query (
"SELECT a.*,
(
SELECT COUNT(1)
FROM ava_users b
WHERE (b.points, b.id) >= (a.points, a.id)
) AS rank
FROM ava_users a
WHERE a.`user` = '$id'"
);
Try this:
SELECT `user`, rank
FROM (
SELECT `user`, ( #rank := #rank + 1 ) as rank
FROM ava_users, ( select (#rank := 0 ) ) rnk
ORDER BY points DESC
) ranks
WHERE `user` = '".$id."'
user is a key word, therefore use user in order to check parameters equality.
Also, mysql_query can only execute 1 query at a time.
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
I have this query:
SET #current_group = NULL;
SET #current_count = 0;
SELECT user_id, MIN( created_at ) as created_at, CASE WHEN #current_group = user_id THEN #current_count WHEN #current_group := user_id THEN #current_count := #current_count + 1 END AS c
FROM notifies
G ROUP BY user_id, c
ORDER BY id desc LIMIT 0 , 10
If i launch it it works
but if i put it in a find_by_sql method like:
Notify.find_by_sql("SET #current_group = NULL; SET #current_count = 0; SELECT user_id, MIN( created_at ) as created_at, CASE WHEN #current_group = user_id THEN #current_count WHEN #current_group := user_id THEN #current_count := #current_count + 1 END AS c FROM notifies GROUP BY user_id, c ORDER BY id desc LIMIT 0 , 10")
It returns this error:
Mysql2::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 'SET #current_count = 0; SELECT user_id, MIN( created_at ) as created_at, CASE WH' at line 1:
How can i do?
thanks
It's because find_by_sql only works with a single statement.
Setting variables happen in separate statements. set specifically is in the Database Administration section, number 12.4.4, and select is in Data Manipulation section, number 12.2.7. Consoles (usually) allow multiple statements, and keep the variables around, but ActiveRecord queries do not.
To allow multiple statements, I think you have to maintain a persistent connection with the database, which Rails doesn't do (edit: normally). But I'm not certain about that - if anyone else knows, I'd love a more definite reason.
Edit: actually, I have a solution for you. Try this:
items = YourModel.transaction do
YourModel.connection.execute("SET #current_group = NULL;")
YourModel.connection.execute("SET #current_count = 0;")
# this is returned, because it's the last line in the block
YourModel.find_by_sql(%Q|
SELECT user_id, MIN( created_at ) as created_at, CASE WHEN #current_group = user_id THEN #current_count WHEN #current_group := user_id THEN #current_count := #current_count + 1 END AS c
FROM notifies
GROUP BY user_id, c
ORDER BY id desc LIMIT 0 , 10
|)
end
All those run in a single transaction, and any variables / settings inside the transaction block will persist between queries. You're still bound to a single statement per query though. There might be a way to do it without an actual transaction wrapping the whole set, but I haven't looked for it - most likely you want one, or you now have a very specific thing to look for if you know you don't.
Enjoy!
Accordingly to the API it is this syntax:
Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
So you might want to try putting it into an array instead of using parenthesis.
Notify.find_by_sql ["SET #current_group = NULL; SET #current_count = 0; SELECT user_id, MIN( created_at ) as created_at, CASE WHEN #current_group = user_id THEN #current_count WHEN #current_group := user_id THEN #current_count := #current_count + 1 END AS c FROM notifies GROUP BY user_id, c ORDER BY id desc LIMIT 0 , 10"]