I have two sql queries. But in Java I can't set variables.
I tried to summarize it to one query. But that not works, because the sql syntax is wrong.
SET #rn = 0;
SELECT *
FROM (SELECT t.id, #rn := #rn + 1 AS rank
FROM stats t
ORDER BY t.points DESC) t2
WHERE t2.id = ?;
If only the SET part is the problem you can do
SELECT t.id, #rn := #rn + 1 AS rank
FROM stats t
CROSS JOIN ( SELECT #rn := 0 ) as parameters
ORDER BY t.points DESC
You can also check this tutorial http://www.mysqltutorial.org/mysql-row_number/
You need to do a join like this :
SELECT stats.id, #rn := #rn+1 AS rank
FROM stats, (SELECT #rn:=0) a
WHERE stats.id = ?
If you have mysql 8.0 you can use: ROW_NUMBER() or RANK() :
SELECT
id,
ROW_NUMBER() OVER w AS 'row_number',
RANK() OVER w AS 'rank',
FROM stats
WHERE stats.id = ?
WINDOW w AS (ORDER BY points);
Related
I've got this query running on two different fiddle sites, both set to use MySQL 5.6:
SELECT name, rank, position FROM(
SELECT name, position,
#rank:= IF(#prev = name, #rank + 1, 1) AS rank,
#prev:= name
FROM (SELECT * FROM drivers
LEFT JOIN results on drivers.id = results.driver_id
JOIN (SELECT #rank := 1) AS init
ORDER BY name, results.position ASC) AS temp
) AS derived WHERE rank <= 3 ORDER BY name, rank
It's supposed to give the top 3 finishing positions of each driver. The query works on fiddle #1, but not on fiddle #2 or the production server, although all three of them are running on MySQL 5.6.
Is there a setting that I'm missing?
Fiddle #1 - working
Fiddle #2 - not working
You can use the following solution:
SELECT name, rank, position FROM (
SELECT name, position,
#rank:= IF(#prev = name, #rank + 1, 1) AS rank,
#prev:= name
FROM (
SELECT *
FROM drivers LEFT JOIN results ON drivers.id = results.driver_id
JOIN (SELECT #rank := 1) AS init_rank
JOIN (SELECT #prev := '') AS init_prev
ORDER BY name, results.position ASC
) AS temp
) AS derived
WHERE rank <= 3
ORDER BY name, rank
I added the initialization for the #prev variable on a JOIN too.
different demos:
demo on db-fiddle.com
demo on sqlfiddle.com
demo on dbfiddle.uk
Since MySQL 8.0 you can use the built-in RANK window function. So you don't need the #prev or #rank variables:
SELECT name, `rank`, position FROM (
SELECT name, position, RANK() OVER (PARTITION BY name ORDER BY name, position) AS `rank`
FROM drivers LEFT JOIN results ON drivers.id = results.driver_id
) AS derived
WHERE `rank` <= 3
ORDER BY name, `rank`
demo on dbfiddle.uk
I recently moved to a shared host that has MySQL 5.6.39 instead of MariaDB 10.x, I was wondering what would the equivalent of the following MariaDB statement in MySQL?
SELECT rank,
total
FROM
(SELECT ROW_NUMBER() OVER (
ORDER BY `prestige` DESC, `xp` DESC) AS rank,
(SELECT COUNT(*)
FROM Modular_LS) AS total,
steamid
FROM Modular_LS) sub
WHERE sub.steamid = '%s'
I got as far as this, but now I'm stuck
SELECT rank, total FROM
(SELECT #rank := #rank +1 as rank FROM Modular_LS,
(SELECT COUNT(*) FROM Modular_LS) AS total, steamid FROM Modular_LS) sub,
(SELECT #rank := 0) r ORDER BY `prestige` DESC, `xp` DESC) t;
The table structure contains the column steamid, xp, prestige
My goal is to order by prestige descending first and then xp descending to put it in a ranking like-order, then using WHERE query to find a specific player's ranking. The output of which contains the rank (position) and the total (total amount of records)
Maybe this will get you started:
SELECT #rank := IF(player_id = #prev, #rank + 1, 1), #prev := player_id
FROM ( SELECT #rank := 1, #prev = 0 ) AS init
JOIN ( SELECT player_id
FROM Modular_LS
ORDER BY prestige DESC, SP DESC
) AS x ;
After a few hours, this is what I came up with that solved my problem.
SELECT
sub.rank
,sub.total
FROM
(
SELECT
t.id
,t.steamid
,#rownum : = #rownum + 1 AS rank
,(
SELECT
COUNT (*)
FROM
Modular_LS
) AS total
FROM
Modular_LS t JOIN (
SELECT
#rownum : = 0
) r
ORDER BY
t.prestige DESC
,t.xp DESC
) sub
WHERE
sub.steamid = '%s'
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;
How to use Sql query for generating S.no from 1. I can't get the answer correctly
SELECT (#cnt := #cnt + 1) AS 'S.No',`barcode`,
(SELECT #cnt := 0) AS dummy
FROM wp_weblib_outitems
Try this:
SELECT #s:=#s+1 AS 'S.No',`barcode`
FROM wp_weblib_outitems,
(SELECT #s:= 0) AS s;
This is my query. i just want S.No as asc . How can i write this query as ascending order
SELECT DISTINCT (subject),a.title, a.callnumber,
a.author, a.recv_date,a.pubdate ,b.book_access_number,(#cnt := #cnt + 1) AS 'S.No'
from wp_weblib_collection a
inner join wp_weblib_book_log_reports b on a.barcode = b.book_access_number
$student
CROSS JOIN (SELECT #cnt := 0) AS dummy
GROUP BY subject asc
You can try with ROW_NUMBER() as given below.......
SELECT ROW_NUMBER() OVER (ORDER BY [Column1]) AS 'NO',[Column1],[column2],.... FROM tblUser;
I am trying to get the rank of specified record, and I have some success with this code:
SELECT `rank`
FROM
(
select #rownum:=#rownum+1 `rank`, p.*
from TableName p, (SELECT #rownum:=0) r
order by point DESC
) s
WHERE names = 'house'
(See the schema here.)
This SQL query works, but if I want to get the result according to city_id and name, I must use two where clauses, and then the code doesn't work.
I want to get rank of house only for its city. How can I do this?
I want to get rank of "house" only for its city
You can do this by introducing another variable to keep track of the city:
SELECT `rank`
FROM (select p.*,
(#rn := if(#c = city, #rn + 1,
if(#c := city, 1, 1)
)
) as rank
from TableName p CROSS JOIN
(SELECT #rn := 0, #c := -1) params
order by city_id, point DESC
) s
WHERE names = 'house' ;
You can also use your original query, with a tweak, if you know that "house" only appears once in the data:
SELECT `rank`
FROM (select p.*, (#rn := #rn + 1) as rank
from TableName p CROSS JOIN
(SELECT #rn := 0) params
where city_id = (select city_id from TableName t2 where t2.names = 'house')
order by point DESC
) s
WHERE names = 'house' ;