In the above table, c position is 3.
Is there any function to find the position in Mysql?
update
try
select #rownum:=#rownum+1 ‘theposition’, t.* from mytable t, (SELECT #rownum:=0) r order by t.USER desc;
Use this:
SELECT x.user,
x.position,
x.number
FROM (SELECT t.user,
t.number,
#rownum := #rownum + 1 AS position
FROM TABLE t
JOIN (SELECT #rownum := 0) r
ORDER BY t.number DESC) x
WHERE x.user = 'c'
You can then get his position from x.position
I recommend you to add an id field. i don't know of any function to do that. you can select * and then in a script language search it or use a subquery. but i don't recommend that.
SELECT
#rowNumber := #rowNumber + 1 'RowNumber',
u.*
FROM Users u,
(SELECT #rowNumber := 0) r
ORDER BY u.User ASC
Related
Right now I have this:
SELECT
#rownum := #rownum + 1 AS rownum,
T1.*
FROM
(
SELECT user.username, points
FROM scores
JOIN users AS user ON user.id = scores.user_id
) AS T1, (SELECT #rownum := 0) AS r
ORDER BY T1.points DESC, rownum ASC
And this returns usernames, points and row number. Points are ordered but row numbers are all messed up. If I put ORDER BY into the nested select then row nubmers are ordered but points are not. So what I need to change so that I get points ordered in descending order and row number would be in ascending, what I wanna create is leaderboards, so that user whit most point is first etc.
It looks like you need your rownum to be paired up with points that have been pre-ordered. Hence you need to move ORDER BY on points into the nested select:
SELECT
#rownum := #rownum + 1 AS rownum,
T1.*
FROM
(
SELECT user.username, points
FROM scores
JOIN users AS user ON user.id = scores.user_id
ORDER BY points DESC
) AS T1, (SELECT #rownum := 0) AS r
ORDER BY rownum ASC
Does this do what you want?
SELECT (#rownum := #rownum + 1) AS rownum,
us.*
FROM (SELECT u.username, s.points
FROM scores s JOIN
users u
ON u.id = s.user_id
ORDER BY s.points DESC
) us CROSS JOIN
(SELECT #rownum := 0) params;
Basically, this just leaves the ordering in the subquery.
If points is not a number, then use ORDER BY (s.points + 0) DESC in the subquery. Or fix the data so it is stored as a number.
Here is my mysql query:
SELECT users.id, user.name, category.id,
GROUP_CONCAT(category.name) AS catName,
#rownum := #rownum + 1 AS row_number
FROM users
JOIN usecat ON id_users=users.id
JOIN category ON id_category=category.id
CROSS JOIN (select #rownum := 0) r
GROUP BY users.id
Result: AAA-1, BBB-3, CCC-8,...
I'd like to get this result: AAA-1, BBB-2, CCC-3,...
Can you help me change this query? Thanks.
Try this:
SET #rownum=1;
SELECT *, #rownum := #rownum + 1 AS row_number
FROM (SELECT users.id, user.name, category.id,
GROUP_CONCAT(category.name) AS catName
FROM users
JOIN usecat ON id_users=users.id
JOIN category ON id_category=category.id
GROUP BY users.id) t;
I have two tables: songs and groups
i want limit the songs are match the group to 3
i tried this:
SELECT
groups.`IDgroup`,
groups.`name` AS g_name,
songs.`IDsong`,
songs.`name` AS s_name
FROM `groups`
LEFT OUTER JOIN songs ON (groups.`IDgroup` = songs.`IDgroup` LIMIT 3)
Put the limit out of parentheses:
SELECT
groups.`IDgroup`,
groups.`name` AS g_name,
songs.`IDsong`,
songs.`name` AS s_name
FROM `groups`
LEFT OUTER JOIN songs
ON groups.`IDgroup` = songs.`IDgroup`
LIMIT 3
It is generally not a good idea to put a limit on a query that does not explicitly order its results. The reason is that it could return different results over time.
So, you may want to consider adding an
ORDER BY groups.IDgroup, songs.IDsong
to your query (before the LIMIT 3), assuming that this combination is unique.
SELECT
g.`IDgroup`,
g.`name` AS g_name,
s.`IDsong`,
s.`name` AS s_name
FROM `groups` g
LEFT OUTER JOIN songs s
using ('idgroup')
LIMIT 3
This query will return the last 3 songs for each group:
SELECT
c.`IDgroup`,
c.`name` AS g_name,
s.`IDsong`,
s.`name` AS s_name
FROM
groups c
JOIN (
SELECT
IF(#C != c.IDgroup, #ROWNUM := 1, #ROWNUM := #ROWNUM +1) AS RN,
#C := c.IDgroup,
c.IDgroup,
s.IDsong,
s.name
FROM groups c
LEFT JOIN songs s ON c.`IDgroup` = s.`IDgroup`
CROSS JOIN (SELECT #C := '') t2
ORDER BY c.IDgroup ASC
) s ON c.`IDgroup` = s.`IDgroup`
JOIN JOIN (
SELECT IDgroup, MAX(rn) AS mx
FROM (
SELECT
IF(#C != c.IDgroup, #ROWNUM := 1, #ROWNUM := #ROWNUM +1) AS rn,
#C := c.IDgroup,
c.IDgroup
FROM groups c
LEFT JOIN songs s ON c.`IDgroup` = s.`IDgroup`
CROSS JOIN (SELECT #C := '') t2
ORDER BY c.IDgroup ASC
) t
GROUP BY IDgroup
) maxsong ON maxsong.IDgroup = c.IDgroup AND s.rn BETWEEN maxsong.mx-2 AND maxsong.mx
ORDER BY c.IDgroup ASC, s.`name` ASC
Fiddle: http://sqlfiddle.com/#!2/b65c3b/1
Take the LIMIT out of the parentheses:
SELECT
groups.`IDgroup`,
groups.`name` AS g_name,
songs.`IDsong`,
songs.`name` AS s_name
FROM `groups`
LEFT OUTER JOIN songs USING (`IDgroup`)
LIMIT 3
I'm a MS-SQL Developer, now I use this query (MySQL) ↓
SELECT A.place_idx,A.place_id,B.TODAY_CNT,C.TOTAL_CNT FROM CUSTOM_LIST
AS A
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TODAY_CNT from COUNT_TABLE where DATE(place_date) = DATE(NOW()) GROUP BY place_id)
AS B ON B.place_id=A.place_id
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TOTAL_CNT from COUNT_TABLE GROUP BY place_id)
AS C ON C.place_id=A.place_id
The result is:
I want this:
Try somethink like this:
SELECT ..., C.TOTAL_CNT, (#r := #r + 1) AS rank FROM CUSTOM_LIST, (SELECT #r := 0) t
...
ORDER BY C.TOTAL_CNT DESC
Whole query:
SELECT A.place_idx,A.place_id,B.TODAY_CNT,C.TOTAL_CNT, (#r := #r + 1) AS rank
FROM CUSTOM_LIST AS A, (SELECT #r := 0) t
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TODAY_CNT from COUNT_TABLE where DATE(place_date) = DATE(NOW()) GROUP BY place_id)
AS B ON B.place_id=A.place_id
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TOTAL_CNT from COUNT_TABLE GROUP BY place_id)
AS C ON C.place_id=A.place_id
ORDER BY C.TOTAL_CNT DESC
What if we got two same values in Total_CNT?
Maybe something like this:
SELECT ..., (#last := C.TOTAL_CNT) AS TOTAL_CNT,
IF(#last = C.TOTAL_CNT, #r, #r := #r + 1) AS rank
FROM CUSTOM_LIST, (SELECT #r := 0, #last := -1) t
...
Updated
RANK() OVER (ORDER BY TOTAL_CNT DESC DESC) AS Rank
Here I got Another Very Good Solution.:
SELECT A.place_idx,A.place_id,B.TODAY_CNT,C.TOTAL_CNT, RANK() OVER (ORDER BY TOTAL_CNT DESC) AS Rank FROM CUSTOM_LIST
AS A
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TODAY_CNT from COUNT_TABLE where DATE(place_date) = DATE(NOW()) GROUP BY place_id)
AS B ON B.place_id=A.place_id
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TOTAL_CNT from COUNT_TABLE GROUP BY place_id)
AS C ON C.place_id=A.place_id
I'm using this query:
SELECT A.place_idx,A.place_id,B.TOTAL_CNT,(#r := #r + 1) AS rank FROM CUSTOM_LIST
AS A
INNER JOIN
(SELECT #r := 0)
AS C
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TOTAL_CNT from COUNT_TABLE GROUP BY place_id)
AS B ON B.place_id=A.place_id order by B.TOTAL_CNT desc;
Which gives this result:
But I want this result:
How do I need to modify my query? What am I doing wrong?
SELECT *,(#r := #r + 1) AS rank FROM
(
SELECT A.place_idx,A.place_id,B.TOTAL_CNT FROM CUSTOM_LIST
AS A
INNER JOIN
(SELECT place_id,COUNT(place_id) AS TOTAL_CNT from COUNT_TABLE GROUP BY place_id)
AS B ON B.place_id=A.place_id order by B.TOTAL_CNT desc
) AS T, (SELECT #r := 0) AS tt
Your C.rank is getting calculated as they are processed, not after they are sorted. There is really no need for this data, anyways. Since you're sorting the rows by your metric, you know the first row is the first rank, etc. You can handle it on the programming side of things after you pull it out.
Alternatively, you can put what you have in an inner select, then do the rank after.