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.
Related
I have select query that selects student scores and ranks them from the highest to the lowest, this mysql query works the first time, but when I run it the second time on phpmyadmin, it returns NULL where it is supposed to show the rank of the student, below is the mysql query;
SELECT #rownum := #rownum + 1 AS rank
, student_name
, avga
FROM `averaga`
WHERE class="Form 1A"
ORDER
BY avga DESC
here is a part snapshot of the results from query results
You need to initialize the variable. I usually do this in query itself:
SELECT (#rownum := #rownum + 1) AS rank, student_name, avga
FROM `averaga` a CROSS JOIN
(SELECT #rownum := 0) params
WHERE class = 'Form 1A'
ORDER BY avga DESC;
Using MySQL/MariaDB, I usually do this kind of query below to get the rank of a specific record so that I can display the proper page in an application:
SET #rownum := 0;
SELECT rank
FROM
( SELECT #rownum := #rownum+1 AS rank, ordid
FROM ord
order by ord_status, ordid
) AS derived_table
WHERE ordid = 1234
limit 1;
I used it for years and it usually works just fine.
However, today, I tried to sort the query according to the description of the order status instead of the order status id (field ord_status). So, I had to sort data using the user funtion named getStatusDescription() that I created in my database. Here is my new query:
SET #rownum := 0;
SELECT rank
FROM
( SELECT #rownum := #rownum+1 AS rank, ordid
FROM ord
order by getStatusDescription(ord_status), ordid
) AS derived_table
WHERE ordid = 1234
limit 1;
For an unknown reason, the rank result is wrong and I do not understand why it is not working. Is it possible that there is a problem or a limitation with MariaDB ?
I'm using MariaDB 10.0.17 on a Centos 7 machine as my development plaftform.
For your information, my function getStatusDescription() just receive a parameter (the order status id) then according to the parameter received select the proper varchar(35) field from a specific table then just return it.
Any help is very welcome.
Guylain Plante
Your method of getting rank is fine, but you can also use a subquery method:
select count(*)
from ord cross join
(select ordid, getStatusDescription(o2.ord_status) as gsd
from ord o2
where o2.ordid = 1234
) oo
where getStatusDescription(ord_status) < oo.gsd or
(getStatusDescription(ord_status) = oo.gsd and o.ordid <= oo.ordid)
As for your situation, I don't know about the root cause. However, sometimes GROUP BY is problematic with variables and an additional subquery fixes the probelm:
SELECT rank
FROM (SELECT #rownum := #rownum+1 AS rank, ordid
FROM (SELECT ord.*
FROM ord
ORDER BY getStatusDescription(ord_status), ordid
) derived_table CROSS JOIN
(SELECT #rownum := 0) params
) o
WHERE ordid = 1234
LIMIT 1;
Finally, I remembered that I had to put a LIMIT (and also a sub-query) so that the database have a good reason to apply the sort order.
The following query works fine now:
SELECT rank FROM (SELECT #rownum := #rownum+1 AS rank, ordid
FROM (SELECT ordid FROM ord order by getStatusDescription(ord_status), ordid LIMIT 9999999999999
) as t2
) AS derived_table
WHERE ordid = 1234 limit 1;
See the following thread as well:
mysql - order by inside subquery
I am working on migration from MS SQL Server to MariaDB 10.0. I have query which use RANK() PARTITION BY. I already created some kind of RANK() implementation on my table but it's not working properly.
The original query was:
RANK() OVER (PARTITION BY visits.id_partner ORDER BY visits.updated_at DESC) AS rank
My implementation for MariaDB/MySQL:
SELECT
...,
(
CASE visits.id_partner
WHEN #currId THEN
#curRow := #curRow + 1
ELSE
#curRow := 1 AND #currId := visits.id_partner
END
) AS rank
FROM
records rec
JOIN visits ON visits.id = rec.id_visit,
(
SELECT
#curRank := 0,
#currId := NULL
) r
WHERE
...
ORDER BY visits.id_partner ASC, visits.updated_at DESC
I want to select row ranked by id_partner order by updated_at field. When id_partner is same as on row before RANK should increase by 1. When is different than before, it should reset to 1.
But my query is not working at all. I have still rank 1 on all rows. Can you help me find mistake?
Thank you for help!
It is tricky to use variables in MySQL/MariaDB. A variable should only be used and assigned in one statement (as you do correctly). However, AND can short-circuit variable assignment.
I use a construct like this for ROW_NUMBER(). RANK() is actually a bit of a pain . . . DENSE_RANK() and ROW_NUMBER() are simpler. However, this seems to be the code that you are aiming for:
SELECT ...,
(#rn := if(#currId = visits.id_partner, #rn + 1,
if(#currId := visits.id_partner, 1, 1)
)
) as rank
FROM records rec JOIN
visits
ON visits.id = rec.id_visit CROSS JOIN
(SELECT #rn := 0, #currId := NULL) params
WHERE
...
ORDER BY visits.id_partner ASC, visits.updated_at DESC;
EDIT:
In MySQL (and presumably in MariaDB), sometimes variables don't work quite right unless you use a subquery. So, try this:
SELECT . . .,
(#rn := if(#currId = visits.id_partner, #rn + 1,
if(#currId := visits.id_partner, 1, 1)
)
) as rank
FROM (SELECT ...
FROM records rec JOIN
visits
ON visits.id = rec.id_visit
WHERE
...
ORDER BY visits.id_partner ASC, visits.updated_at DESC
) t CROSS JOIN
(SELECT #rn := 0, #currId := NULL) params;
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
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