最佳平均评分

Best average rating

我为新闻文章创建了一个简单的评级系统。新闻文章存储在名为 'articles' 的数据库 table 中。每篇文章都有一个唯一的id,从1开始。

所以我有 2 篇文章,ID 1 和 ID 2。

我还有一个名为 'ratings' 的 table,它采用用户的唯一 ID、文章 ID 和用户给出的评分。

如果我给 ID 2 的文章 5/5 星评级,它进入 'ratings' table,文章 ID 2,我的用户 ID 和评级 5。

我想出了如何显示每篇文章的平均评分,但我想了解如何按降序显示文章的最佳平均评分。这可能吗?这怎么可能?

以下是我求平均值的方法:

<?
    $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;
?>

MySQL 有一个 avg 函数,您可以使用它来代替自己实现这个逻辑。从那里开始,这只是按文章 ID 分组并按平均值排序的问题:

SELECT   articleID, AVG(vote)
FROM     ratings
GROUP BY articleID
ORDER BY 2 DESC

这样做的最佳做法是在您的文章 table 中添加一个名为 average_rating 的新专栏,并使用 cron 作业或在每次投票后更新它。

请记住,一段时间后您的评分 table 会变得很大,并且在每次刷新页面时计算平均评分会给您的服务器带来巨大的负载。

我会在这一个中使用去规范化。 我会使用触发器来更新先前在 table 篇文章上创建的列,该列将存储它的平均评分。

我会发布一个触发器示例,但您没有发布您使用的是哪个数据库。

Mysql: https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html

PostgreSQL: https://www.postgresql.org/docs/9.1/sql-createtrigger.html

每次完成、更新或删除评级时,触发器都会使用内置的 avg 函数将此列更新为当前平均值。

最后,您只需在按此评分列描述排序的文章 table 上创建一个 select。

并在此平均评分列上创建索引以获得更快的结果。

SELECT   articleID, AVG(vote)
FROM     ratings

GROUP BY articleID,vote

ORDER BY  DESC

使用了这个查询