MySQL get top average entries - mysql

I am trying to write a mysql query to return the top 3 courses that have the highest average course rating. I have two tables, Ratings and Courses.
The Ratings table:
courseId rating
1 6
2 2
1 4
2 5
3 3
4 0
6 0
The Courses Table:
courseId cnum cname
1 100 name1
2 112 name2
3 230 name3
4 319 name4
5 122 name5
6 320 name6
I need to return the top 3 courses that have the highest average rating. Any ideas how I could do this? Thanks

SELECT Courses.*
FROM Courses NATURAL JOIN (
SELECT courseId, AVG(rating) avg_rating
FROM Ratings
GROUP BY courseId
ORDER BY avg_rating DESC
LIMIT 3
) t
See it on sqlfiddle.

Related

Count and Distinct SQL query

I have a table of Books, that contains the following columns:
Book_Id User_Id
001 1
002 2
001 1
004 2
005 3
006 3
007 2
008 2
009 1
Where :
Book_Id - identifier of a book that a user read; User_Id - identifier
of a reader/user.
Let's assume that User1 read books three times, but 2 of them were same, so the user 1 read 2 distinct books (001 and 009). User 2 read 4 distinct books, while user 3 read 2 distinct books.
In overall, there are 2 users that read 2 distinct books, and 1 user that read 4 distinct books.
The output expected is as below:
Distinct_Books_Count --- User_Count
2 2
4 1
I tried the following:
SELECT COUNT(DISTINCT Book_Id), COUNT(User_Id) FROM Books GROUP BY
User_Id
But I receive the following table:
Distinct_Books_Count User_Count
2 3
4 4
2 2
So any alternative solution or changes?
I call this a "histogram of histograms" query. You can do it using two group bys:
SELECT num_books, COUNT(*)
FROM (SELECT b.User_Id, COUNT(DISTINCT Book_Id) as num_books
FROM Books b
GROUP BY User_Id
) b
GROUP BY num_books
ORDER BY num_books;

Use avg() and joins mysql

Say I have a table called students
idStudent Name
1 Billy
2 Mariah
3 Chris
4 Mark
5 Sarah
and another table called tests
idTest score student_idstudent
1 50 1
2 100 1
3 90 2
4 100 3
5 45 4
is it possible to use a combination of a join and avg() to get a result like
idStudent avg_test
1 75
2 90
3 100
4 45
5 0
SELECT s.idStudent,
AVG(COALESCE(t.score, 0)) AS avg_test
FROM students s
LEFT JOIN tests t
ON s.idStudent = t.student_idStudent
GROUP BY s.idStudent

MySQL: return first row from join

I have 2 tables "quizzes" & "users", I need to return list of first user took each quiz, with quiz_id:
tables structure
"quizzes" structure:
id name
1 England
2 france
3 Japan
4 USA
5 UAE
6 Sweden
7 Italy
8 Brazil
9 South Korea
10 India
"users" structure:
id user_id quiz_id
1 1 1
2 1 2
3 2 1
4 3 4
5 1 4
6 5 9
7 2 9
8 3 8
9 3 9
10 3 7
I need to run query to return first "user_id" took each "quiz", (order by users.id ASC)
expected results:
quiz_id user_id
1 1
2 1
4 3
7 3
8 3
9 5
thanks,
You first group by quiz and pick minimal id and then select based on those ids:
select quiz_id, user_id
from users
where id in(select min(id) from users group by quiz_id)
Select quiz_id, user_id
from users
Where (quiz_id, id) in
(
Select quiz_id, min(id) id
From users
Group by quiz_id
)

My sql query sum of highest points for each category

upload table
id category_id
1 1
2 2
3 3
4 1
In Ratings Table
id upload_id points
1 1 5
2 2 3
3 3 2
4 4 2
5 1 5
I want to display all the records from ratings table except id 4 because id 4 is the same category id 1
I excepted result
Uploaded_id 1 has sum of 10 points
Uploaded_id 2 has sum of 3 points
Uploaded_id 3 has sum of 2 points
Please help me.
Thanks In advance
Sasikumar
select upload_id, sum(points)
from rating r,
(select min(id) id from upload group by category_id) a
where a.id = r.upload_id group by upload_id

Add total of 3 rows for specific id

I have three tables:
Students
-------------------------------------------------------------
studentId first last gender weight
-------------------------------------------------------------
1 John Doe m 185
2 John Doe2 m 130
3 John Doe3 m 250
Lifts
-------------------
liftId name
-------------------
1 Bench Press
2 Power Clean
3 Parallel Squat
4 Deadlift
5 Shoulder Press
StudentLifts
------------------------------------------------
studentLiftId studentId liftId weight
------------------------------------------------
1 1 1 185
2 2 3 130
3 3 1 190
4 1 2 120
5 2 1 155
6 3 2 145
7 1 1 135
8 1 1 205
9 2 3 200
10 1 3 150
11 2 2 110
12 3 3 250
I would like to have four top lists:
Bench Press
Parallel Squat
Power Clean
Total of the above 3
I can successfully grab a top list for each specific lift using the following query:
SELECT s.studentId, s.first, s.last, s.gender, s.weight, l.name, sl.weight
FROM Students s
LEFT JOIN (
SELECT *
FROM StudentLifts
ORDER BY weight DESC
) sl ON sl.studentId = s.studentId
LEFT JOIN Lifts l ON l.liftId = sl.liftId
WHERE l.name = 'Bench Press'
AND s.gender = 'm'
AND s.weight > 170
GROUP BY s.studentId
ORDER BY sl.weight DESC
However, I am stuck on how to add the highest total of each lift for each student. How can I first find the highest total for each student in each lift, and then add them up to get a total of all three lifts?
Edit
The result set that I am looking for would be something like:
-------------------------------------------------
studentId first last weight
-------------------------------------------------
3 John Doe3 585
1 John Doe 475
2 John Doe2 465
I also forgot to mention that I would actually like two lists, one for students above 170 and one for students below 170.
SELECT -- join student a total weight to the student table
A.studentId,
A.first,
A.last,
C.totalWeight
FROM
Student A,
(
SELECT -- for each studet add the max weights
sum(B.maxWeight) as totalWeight,
B.studentID
FROM (
SELECT -- for each (student,lift) select the max weight
max(weight) as maxWeight,
studentId,
liftID
FROM
StudentLifts
GROUP BY
studentId,
liftID
) B
GROUP BY
studentId
) C
WHERE
A.studentID = C.studentId
-- AND A.weight >= 170
-- AND A.weight < 170
-- pick one here to generate on of the two lists.