Reputation: 175
I have created a simple rating system for news articles. The news articles are stored in the database table called 'articles'. Each article has a unique id, starting from 1.
So I have 2 articles, ID 1 and ID 2.
I also have a table called 'ratings' that takes the users unique ID, the article ID and the rating that the user gave.
If I give an article with ID 2 a 5/5 star rating, it goes into the 'ratings' table, with article ID 2, my user ID and the rating of 5.
I have figured out how to display the average rating of each article, but I would like to find out how to show the BEST average rating of articles in descending order. Is that at all possible? How could this be done?
Here is how I find the average:
<?
$votesForThis = 0;
$sql = "SELECT * FROM ratings WHERE articleID = ".$articleID." ORDER BY id ASC";
// Check if there are results
if ($result = mysqli_query($con, $sql)) {
// Loop through each row in the result set
while($row = mysqli_fetch_assoc($result)) {
$votesForThis++;
}
}
$result = mysqli_query($con, 'SELECT SUM(vote) AS vote_sum FROM ratings WHERE articleID=' . $articleID);
$row = mysqli_fetch_assoc($result);
$voteSum = $row['vote_sum'];
$averageVotes = $voteSum / $votesForThis;
?>
Upvotes: 0
Views: 142
Reputation: 18012
I would use de-normalization in this one. I would use triggers to update a previously created column on table articles which would store it's average rating.
I would have posted an example of trigger but you haven't posted which database are you using.
Mysql: https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html
Postgresql: https://www.postgresql.org/docs/9.1/sql-createtrigger.html
Each time a rating it's done, updated or deleted a trigger would update this column with it's current average using the built-in avg function.
At the end you'll only have to create a select on the articles table ordered by this rating column desc.
And create an index on this average rating column to have even faster results.
Upvotes: 1
Reputation: 208
SELECT articleID, AVG(vote)
FROM ratings
GROUP BY articleID,vote
ORDER BY DESC
used this Query
Upvotes: 0
Reputation: 371
The best practice for doing this is to add a new column to your article table called average_rating and update it with a cron job or after every voting.
Keep in mind that after a while your rating table will become giant and calculating average rating on every page refresh will put huge load on your server.
Upvotes: 2