Reputation: 1138
I have a Course model which has_many reviews. My Review model has a rating field. What I would like is a query to find the top rated courses. I want to do this in the SQL in order to avoid returning all the course objects and then trying to rank and sort them.
Upvotes: 0
Views: 1142
Reputation: 34784
You don't describe how you define "top rated". It could be that you want the courses with the highest individual ratings:
Course.joins(:reviews).group("courses.id").order("reviews.rating desc")
Or you might want the courses with the highest total ratings:
Course.joins(:reviews).group("courses.id").order("sum(reviews.rating) desc")
Then on each of these you can call first(10)
to get the top ten by whichever criteria you want.
Upvotes: 2
Reputation: 7693
I would try this SQL:
SELECT courses.* FROM
(SELECT courses.*, count(*) as rating_no
FROM courses
JOIN reviews ON reviews.course_id = courses.id
GROUP BY reviews.course_id ) as res
ORDER BY rating_no DESC
the idea: You first take all data for each course, along with number of ratings. Then you just sort them. My experinece in MySQL is that GROUP BY and ORDER BY do not like each other, and that is why I used subquery. You might want to try on one query first though, but I doubt it will work :) If you are not interstend in just number of ratings, but for example actual average rate, you can make query like
SELECT courses.* FROM
(SELECT courses.*, (SUM(reviews.rating)/count(*)) as avg_rating
FROM courses
JOIN reviews ON reviews.course_id = courses.id
GROUP BY reviews.course_id HAVING count(*) > 0) as res
ORDER BY rating_no DESC
having count(*) >0 is most likely not needed, but just in case I have added it, to point out that you should avoid dividing by 0.
Upvotes: 2
Reputation: 1888
you may try this
select * from courses where review=(select max(rating) from table)
or
select top 1.* from courses order by review desc
Upvotes: 0
Reputation: 426
Try this
@courses = Course.find(:all, :joins => "INNER JOIN reviews ON reviews.courses_id = courses.id", :order => "reviews.rating DESC")
or RAW sql
`SELECT `courses`.* FROM `courses` INNER JOIN reviews ON reviews.courses_id = courses.id ORDER BY reviews.rating DESC`
Upvotes: 0