计算列为另一个表中其他数据的平均值

时间:2018-03-28 23:29:45

标签: mysql sql

我正在创建一个简单的电影网站,允许用户浏览电影标题,并使用5分制评级系统为电影评分。我正在使用XAMPP和phpAdmin通过SQL语言存储我的数据库。我在下面的表格中存储了评分:

*

我在下面的表格中存储了电影:

CREATE TABLE `movie_ratings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `movie_id` int(11) DEFAULT NULL,
  `rating` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

我想在我的电影表中添加一个列average_rating,它基本上从特定movie_id的movie_ratings中获取所有评级值并对其进行平均,然后将值存储到电影表中新的average_rating列中。

我相信我需要一个计算列,但我只知道如何通过同一个表中的列来执行此操作,这里我使用另一个表。我看到一个视图也是可能的......我宁愿将电影的平均评分存储为新列。

所以我创建了一个VIEW,但它只显示一部电影和平均值。

CREATE TABLE `movies` (
  `movie_title` varchar(255) NOT NULL,
  `movie_id` int(100) NOT NULL,
  `genre` text NOT NULL,
  `release_date` text NOT NULL,
  `price` int(100) NOT NULL,
  `year` year(4) NOT NULL,
  `description` text NOT NULL,
  `movie_image` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

2 个答案:

答案 0 :(得分:0)

您需要group by子句

CREATE VIEW movie_ratings_view
AS
SELECT
      b.movie_id
    , b.movie_title
    , b.movie_image
    , b.price
    , AVG(br.rating) AS avgRating
FROM movies b
INNER JOIN movie_ratings br ON b.movie_id = br.movie_id
GROUP BY
      b.movie_id
    , b.movie_title
    , b.movie_image
    , b.price
;

另一种选择(如果/当子视图在MySQL的视图的from子句中被允许):

CREATE VIEW movie_ratings_view
AS
SELECT
      m.movie_id
    , m.movie_title
    , m.movie_image
    , m.price
    , COALESCE(mr.numRatings, 0) AS numRatings
    , COALESCE(mr.avgRating, 0)  AS avgRating
FROM movies m
LEFT JOIN (
      SELECT
            movie_id
          , COUNT(rating) AS numRatings
          , AVG(rating)   AS avgRating
      FROM movie_ratings
      GROUP BY movie_id) mr ON m.movie_id = mr.movie_id
;

答案 1 :(得分:0)

视图最有效的代码可能是相关的子查询:

CREATE VIEW movie_ratings_view AS
    SELECT m.movie_id, m.movie_title, m.movie_image, m.price
           (SELECT AVG(mr.rating)
            FROM movie_ratings mr
            WHERE mr.movie_id = m.movie_id
           ) as avgRating
    FROM movies m;

这可以使用movie_ratings(movie_id, rating)上的索引。并且它没有外部GROUP BY可能很昂贵。

略有不同,因为这会返回没有评级的电影 - 但这甚至可能是理想的。