user_id | date | point
1 20 4
2 20 3
3 20 2
1 21 1
2 21 3
3 21 5
1 23 2
2 23 4
3 23 5
And query:
SELECT user_id, SUM(point) AS point, #row:=#row+1 rank FROM users GROUP BY user_id
How to show rank in this query ?
first you need to delcare #row as variable first
Something like set #row=0; select user_id,SUM(point) as point,#row := #row + 1 as rank from users GROUP BY user_id order by SUM(point) desc;
try this
SET #row=0;
SELECT user_id, SUM(point) AS point, #row:=#row+1 rank FROM users GROUP BY user_id
You can work around the declaring part using this way:
SELECT user_id, SUM(point) AS point, #row:=#row+1 rank FROM users, (SELECT #row := 0) r GROUP BY user_id
I guess you've to write it like:
SELECT user_id, SUM(point) AS point, #row:=#row+1 AS rank FROM users GROUP BY user_id JOIN (SELECT #row := 0) r;
Try this..
SELECT user_id,points, #row:=#row+1 AS Row
from (
SELECT user_id,
SUM(point) AS points rank
FROM users
GROUP BY user_id
Sort by points);
Should have an AS to alias #row to rank, and an order by on point to get them in the right order to rank:-
SELECT user_id, SUM(point) AS point, #row:=#row+1 AS rank
FROM users
CROSS JOIN (SELECT #row:=0) Sub1
GROUP BY user_id
ORDER BY point DESC
Related
I am struggling to find an optimal solution for the following problem.
Suppose I have a table 'Table' like this:
id name report_id
1 name1 1
2 name2 3
3 name3 5
4 name1 7
5 name3 8
....................
I want to select for each value in a set: ('name1', 'name2') 10 random unique rows.
Of course it is possible to do with union like:
(SELECT * FROM Table
WHERE
name='name1'
ORDER BY RAND() LIMIT 10)
UNION
(SELECT * FROM Table
WHERE
name='name2'
ORDER BY RAND() LIMIT 10)
But if I have 100 unique names for which I have to select 10 random records - this query is going to be a bit large.
SQLFiddle demo
select ID,NAME,REPORT_ID
from
(
select *, #row:=if(name=#name,#row,0)+1 as rn, #name:=name from
(select *,RAND() as trand from t) t1,
(select #row:=0,#name:='') tm2
order by name,trand
) t2
where rn<=10
Try this:
SELECT
id,
name,
report_id
FROM
(
SELECT id,
report_id,
name,
CASE WHEN #name != name THEN #rn := 1 ELSE #rn := #rn + 1 END rn,
#name:=name
FROM (SELECT * FROM tbl ORDER BY RAND()) a,
(SELECT #rn:=0, #name := NULL) r
ORDER BY name
) s
WHERE rn <= 10;
SQL FIDDLE DEMO
This doesn't work in MySQL, but in PostgreSQL you can use partition by
select name,report_id from
(select name,report_id,row_number()
over
(partition by name order by random())
as rn from Table) a
where rn<=10
I had this same question and found this answer from a colleague.
In my table i have something like
id file_id
1 1
1 2
1 4
2 1
2 4
2 6
I need to find the most frequent file_id regardless of the id, so for example i need the output something like
file_id count
1 2
4 2
.. ..
Im using php and phpmyadmin
Use this query
select
file_id,
count(*) as count
from table_name
group by file_id;
select file_id, count(*) as count
from files
group by file_id
SELECT file_id, count(id)
FROM f
GROUP BY file_id
ORDER BY count(file_id) DESC;
In standard SQL, you can do:
select f.file_id, cnt
from (select file_id, count(*) as cnt,
rank() over (order by count(*) desc) as seqnum
from t
group by file_id, id
) f
where seqnum = 1;
Simple SQL in your case:
select file_id, count(id)
from ur_table
group by file_id;
Using aggregate function
SELECT count(id) AS count FROM table GROUP BY file_id
I have a Ranking board for the best first 100 blogs for each gender Males and Females.
I have a blogs table:
PRIMARY
blogs_id users_id blogs_score blogs_score_time gender
1 11 2852 2015-09-09 05:21:51 m <-- same score but older date
2 23 2146 2015-09-10 07:31:54 m
3 23 2146 2015-09-10 07:32:26 m
4 23 2852 2015-09-10 04:42:15 m <-- same score but newer date
5 51 1793 2015-09-11 08:15:55 f
6 88 2947 2015-09-11 09:33:18 f
I have a users table:
PRIMARY
id best_rank gender
11 0 m
23 0 m
51 0 f
88 0 f
I need to COUNT best ranks (using MAX(blogs_score) and MAX(blogs_score_time)) for each user from Blogs table and INSERT/UPDATE the Users table with the best ranks for the first 100 users of each gender with highest ranks, so the result should be:
PRIMARY
id best_rank gender
11 2 m
23 1 m
51 2 f
88 1 f
Where user id 11 has best rank of 2 because user id 11 has same score with user 23 but older date than user 23. Where user 51 has rank 2 because of Female's group. I have added column blogs_score_time to prevent tie ranking. And the date 2015-09-10 means September 10.
The final idea is to show the Rank position in user's profile and once someone voted (blogs_score changes in the blogs table), the best_rank column in the users table must be updated with the new ranks recalculation for ALL 100 users who has the best ranks in particular gender group.
How to adapt and fix this (not working) query to my needs?
$sql->query("UPDATE users
JOIN (SELECT b.users_id,
#curRank := #curRank + 1 AS rank,
MAX(blogs_score), MAX(blogs_score_time)
FROM blogs b
JOIN (SELECT #curRank := 0) r
ORDER BY b.blogs_score DESC, p.blogs_score_time DESC LIMIT 100
) ranks ON (ranks.users_id = users.id)
SET users.best_rank = ranks.rank");
Or how to adapt and fix this (not working) query
$sql->query("INSERT INTO users (best_rank, id)
SELECT #rank := #rank + 1 AS rank, b.users_id
FROM blogs b
LEFT JOIN users u ON b.users_id = u.id
GROUP BY b.users_id, b.blogs_score, b.blogs_score_time, b.gender
ORDER BY b.blogs_score DESC, b.blogs_score_time DESC
ON DUPLICATE KEY UPDATE best_rank = VALUES(rank)");
Please help me with the query to solve it. I didn't find any similar solution on stackoverflow and it seems very complicated for me to write such a query alone.
Thanks a lot in advance!
UPDATE users u, (
SELECT
(
CASE gender
WHEN #curType
THEN #curRow := #curRow + 1
ELSE #curRow := 1 AND #curType := gender END
) + 1 AS rank, users_id, blogs_score, blogs_score_time, gender
FROM blogs,
(SELECT #curRow := 0, #curType := '') r
ORDER BY gender, blogs_score DESC, blogs_score_time DESC
) r1
SET u.best_rank = r1.rank
WHERE
u.id = r1.users_id
It does 2 works:
inner select query generates rank as per gender, score and time
updates user table with respective rank.
I think you should add the a GROUP BY clause this way before ORDER BY
$sql->query("UPDATE users
JOIN (SELECT b.users_id,
#curRank := #curRank + 1 AS rank,
MAX(b.blogs_score), MAX(b.blogs_score_time )
FROM blogs b
JOIN (SELECT #curRank := 0) r
GROUP BY b.user_id, rank
ORDER BY b.blogs_score DESC, p.blogs_score_time DESC LIMIT 100
) ranks ON (ranks.users_id = users.id)
SET users.best_rank = ranks.rank");
I have two tables:
teams
---------------------
team_id team_name
---------------------
1 Lakers
2 Clippers
3 Grizzlies
4 Heat
results
...............................................................
game_id team_id1 team_id2 team1_score team2_score
1 1 2 20 30
2 1 3 40 50
3 2 1 50 60
4 4 2 20 30
5 1 2 20 30
My question is, how can I then create standings results for this tables based on results sorted by points, like this:
...............................................................
Position team_name total_points games_played
1 Lakers 140 4
2 Clippers 110 3
3 Grizzlies 50 1
4 Heat 20 1
I guess what you would like to do is something like this:
EDITED
SET #num :=0;
SELECT (#num := #num + 1) as Position,team_name,total_points,games_played
FROM (
SELECT teams.team_name, SUM(p) as total_points, count(*) as games_played
FROM (
SELECT team_id1 as id, team1_score as p FROM results
UNION ALL
SELECT team_id2 as id, team2_score as p FROM results
) t
INNER JOIN teams ON t.id = teams.team_id
GROUP BY id,teams.team_name ) t2
ORDER BY total_points DESC;
SQLFiddle is here : http://www.sqlfiddle.com/#!2/5bf2c/1
If you would like to display all teams, even if some teams did not play a single game, you could go like this:
SET #num :=0;
SELECT (#num := #num + 1) as Position,team_name,total_points,games_played
FROM (
SELECT
teams.team_name,
SUM(p) as total_points,
SUM(f) as games_played
FROM (
SELECT team_id1 as id, team1_score as p, 1 as f FROM results
UNION ALL
SELECT team_id2 as id, team2_score as p, 1 as f FROM results
UNION ALL
SELECT team_id as id, 0 as p, 0 as f FROM teams
) t
INNER JOIN teams ON t.id = teams.team_id
GROUP BY id,teams.team_name ) t2
ORDER BY total_points DESC;
SQLFiddle is here: http://www.sqlfiddle.com/#!2/8ecf5d/9
Hope this helps.
I may have renamed a couple of your columns... oh, and teams 1 and 2 are tied so you need to say a little more about how to resolve that...
SELECT t.*
, COUNT(*) p
, SUM(score) pts
FROM
(
SELECT home_team_id team_id,home_team_score score FROM results
UNION ALL
SELECT away_team_id,away_team_score FROM results
) x
JOIN teams t
ON t.team_id = x.team_id
GROUP
BY t.team_id
ORDER
BY pts DESC;
select team_id,team_name,sum(sc1) ,sum(ct1) from
(select team_id,teams.team_name,sc1,ct1 from
(select team_id1,sum(team1_score)as sc1,count(team_id1) as ct1 from results group by team_id1) as srtbl1,teams
where srtbl1.team_id1 =teams.team_id
union
select team_id,teams.team_name,sc2,ct2 from
(select team_id2,sum(team2_score)as sc2 ,count(team_id2) as ct2 from results group by team_id2) as srtbl2,teams
where srtbl2.team_id2 =teams.team_id) sctbl
group by team_id;
and I think you make a mistake in calculating .
I found some good answers for this question, but I can't really get them to work.
I wan't to get a players rank from a hiscore table.
id name score
1 John 10
2 Linda 5
3 Emmy 25
I want to pass in a name in the query (Linda) and get her rank (She only have 5 points in the table above), and get her rank (nr 3).
I found a similar question with this answer, but don't understand it:
SELECT uo.*,
(
SELECT COUNT(*)
FROM users ui
WHERE (ui.points, ui.id) >= (uo.points, uo.id)
) AS rank
FROM users uo
WHERE id = #id
Thanks in advance
SELECT (COUNT(*) + 1) AS rank FROM hiscore WHERE score > (SELECT score FROM hiscore WHERE name = 'Linda')
Try this query -
SELECT name, score, rank FROM
(SELECT *, #r:=#r + 1 rank FROM table_name ORDER BY score DESC) t1,
(SELECT #r:=0) t2
WHERE name = 'Linda'
SET #rownum := 0;
SELECT rank, name, score
FROM
(SELECT #rownum := #rownum + 1 AS rank, name, score
FROM players
ORDER BY score DESC)