I have a table which stores the rating given by the user.
eg:
UserId Rating
3 1
3 2
1 1
1 2
1 3
1 4
2 1
2 23
2 4
I need to retrieve the 10 users who have rated the maximum number of times.
eg:
1 rated 4 times
2 rated 3 times
3 rated 2 times...
Any idea how to write a query using mysql?
You have to group by userID, count the grouped rows, and order by the count in descending order, then you limit the query to 10 rows:
SELECT userID, count(*) times
FROM users
GROUP BY userID
ORDER BY times DESC
LIMIT 10
If you need the output exactly as shown above, try this:
SELECT CONCAT_WS(' ', userID, 'rated', count(*), 'times')
FROM users
GROUP BY userID
ORDER BY count(*) DESC
LIMIT 10
See this fiddle.
Related
I have a table name POEMS with columns poemID and userID. I want to make the poemID distinct and show only the count in the userID column. There are 3 poemID's with 1. I want to make it show poemID 1 and userID would be 2. poemID 2 and userID 3, for the 3 rows and poemID 3 with userID 1 for the 1 row.
|poemID | userID|
1 1
1 5
2 2
2 5
2 4
3 2
I want the above table to look like the table below.
|poemID | userID |
1 2
2 3
3 1
My SQL query im trying is below but its not working. Please help.
SELECT DISTINCT(poemID), COUNT(userID) FROM POEMS GROUP BY poemID;
This looks like a straight aggregation query:
SELECT poemID, COUNT(*) no_users
FROM POEMS
GROUP BY poemID;
Or, if the same user may appear multiple times for a given poem and you want to count it only once:
SELECT poemID, COUNT(DISTINCT userID) no_distinct_users
FROM POEMS
GROUP BY poemID;
I'm trying to return the users with the top 5 highest scores in a database and assign each user a rank, which I can then display in a high score table. I want the high-score table to contain a maximum of 5 rows, but I also want it to show the rank of the logged-in user amongst the other players. Let's say the logged-in user is 'jennie'.
SELECT *
FROM (
SELECT *, #i := #i+1 i,
(SELECT COUNT(DISTINCT highscore) FROM users s
WHERE s.highscore>=r.highscore) AS rank
FROM users r JOIN (SELECT #i:=0) vars
ORDER BY highscore DESC
) x
WHERE name = 'jennie'
OR i <= 5
ORDER BY rank ASC;
(Using MySQL 5.0.96). Here is a fiddle showing off the query. My issue is the query operates differently based on one condition:
1: If jennie is in the top 5 results, 5 rows will be returned, containing jennie amongst the other users.
2: If jennie is not in the top 5 results, 6 rows will be returned, where the last row contains jennie.
How can I use somehow truncate the list of top users in case 2, from 5 users down to 4 users, so when jennie appears on the end she makes up the 5th row? Thanks for your help.
You can achieve your desired result by doing some clever ordering. First we order by whether rank is <= 4, then by whether the user is 'jennie' and her rank is > 5, and then by rank. This way, if jennie is outside the top 5, she will show as 5th; if she is inside the top 5, she will show in the appropriate position (because of the final order by rank).
SELECT *
FROM (SELECT u1.userid, u1.name, COUNT(u2.userid) + 1 AS rank
FROM users u1
LEFT JOIN users u2 ON u2.highscore > u1.highscore
GROUP BY u1.userid) r
ORDER BY rank <= 4 DESC, name = 'jennie' AND rank > 5 DESC, rank
LIMIT 5;
Output (for your sample data)
userid name rank
4 harry 1
7 phil 2
2 james 3
1 sam 4
6 jennie 7
Demo on dbfiddle
Output (for when jennie's score is 40)
userid name rank
4 harry 1
7 phil 2
6 jennie 3
2 james 4
1 sam 5
Demo on dbfiddle
Note I prefer to do ranking via LEFT JOIN queries, as variables can be problematic...
I have a table called "UserPlay" which as values like this
th_id route_id
1 1
1 2
1 2
1 3
1 3
I just want least time rout_id is used
I have to get output as this
th_id route
1 1
If I understand correctly, you want the route_id with the lowest count:
select route_id, count(*)
from UserPlay u
group by route_id
order by count(*) asc
limit 1;
You can get the list of the_id on it by including group_concat(the_id).
How can I count the total number of records, the number of unique of users and number of records on which the status is 2 from the table participants in one query?
I know how to accomplish this using 3 separate queries:
SELECT COUNT() FROM participants
SELECT COUNT() FROM participants GROUP BY user
SELECT COUNT(*) FROM participants WHERE status = 2
But this doesn't really seem efficient?
Table participants
id user status
10 john#example.com 1
11 john#example.com 1
12 john#example.com 1
13 sally#mailing.com 1
14 sally#mailing.com 2
15 edward#halloworld.com 1
16 edward#halloworld.com 1
17 edward#halloworld.com 2
18 mike#bestmail.net 2
19 mike#bestmail.net 1
29 nat#worldcom.com 0
Just use conditional aggregation:
select count(*) as numrecords, count(distinct user) as numusers,
sum(status = 2) as numstatus_2
from participants p;
Since you want just one result (per requirement), you don't need a group by clause at all, and all of these requirements can be created as arguments for the count function:
SELECT COUNT(*) AS total_records,
COUNT(DISTINCT user) AS distinct_users_count,
COUNT(CASE status WHEN 2 ELSE NULL END) AS status_2_count
FROM participants
I have a table:
quiz userid attempt grade
1 3 1 33
1 3 2 67
1 3 3 90
1 3 4 20
Now, I want the last two attempts i.e., 4 and 3 and I want average grade of these 2 grades i.e, 90 and 20
Could anyone help me?
Use ORDER and LIMIT to get the 2 last attempts and the AVG aggregation function :
SELECT AVG(grade) AS average FROM (
SELECT grade FROM table
WHERE userid = 3
ORDER BY attempt DESC LIMIT 2) AS t
If you want to list both test results separately, with the average in each row, then something like this maybe (otherwise you just need the subquery for the average of the two tests):
SELECT userid, attempt, grade,
( SELECT AVG(grade)
FROM table
ORDER BY attempt DESC LIMIT 0, 2 ) AS avg_grade
FROM table
ORDER BY attempt DESC LIMIT 0, 2;