Mysql从存储在3个表中的事物中选择一列的平均值

Mysql Selecting the average value of a column from things that are stored in 3 tables

我对数据库还很陌生,刚开始使用 mysql。

我有 4 个表(moviegenremovieGenremovieRating):

movie:

CREATE TABLE `movie` (
  `movieId` INT NOT NULL,
  `title` VARCHAR(155) NOT NULL,
  PRIMARY KEY  (`movieId`)
);

genre

CREATE TABLE `genre` (
  `code` INT NOT NULL AUTO_INCREMENT,
  `genre` VARCHAR(20) NOT NULL,
  PRIMARY KEY  (`code`)
);

movieGenre

CREATE TABLE `movieGenre` (
  `movieId` INT,
  `genreId` INT,
  CONSTRAINT `fk_movieGenre_movie` FOREIGN KEY (`movieId`) REFERENCES `movie`(`movieId`),
  CONSTRAINT `fk_movieGenre_genre` FOREIGN KEY (`genreId`) references `genre`(`code`)
);

movieRating

CREATE TABLE `movieRating` (
  `userId` INT NOT NULL AUTO_INCREMENT,
  `movieId` INT NOT NULL,
  `rating` FLOAT NOT NULL,
  `date` DATE,
  CONSTRAINT `fk_movieRating_user` FOREIGN KEY (`userId`) REFERENCES `user`(`userId`),
  CONSTRAINT `fk_movieRating_movie` FOREIGN KEY (`movieId`) REFERENCES `movie`(`movieId`)
);

我需要找到每个电影类型的平均评分,按平均评分值降序排列,如果一个类型没有任何相关的评分,它应该报告为 0 评分值

我迷路了。我不知道如何实现这个结果。你能帮帮我吗?

我已经想出如何找到每部电影的平均评分,但我不知道如何更改它,所以我为每个类型找到:

SELECT `movie`.`movieId`, AVG(`movieRating`.`rating`) FROM `movie`
INNER JOIN `movieRating` ON `movie`.`movieId` = `movieRating`.`movieId`
GROUP BY `movieRating`.`movieId`
ORDER BY AVG(`movieRating`.`rating`) DESC;

你应该左连接所有表,然后按 gerne 分组

SELECT `genre`,AVG(IFNULL(`rating`,0)) avgrate
FROM `movie` m
LEFT JOIN `movieRating` mr ON m.`movieId` = mr.`movieId`
LEFT JOIN movieGenre mg ON mg.`movieId` = m.`movieId` 
LEFT JOIN `genre` g ON g.`code` = mg.`genreId`
GROUP BY `genre`

我通常为你的表生成数据,然后开始连接表,看看你是否得到你想要的结果,如果没有将连接更改为 LET 一个接一个地连接直到你得到你想要的结果,当然你需要计算 3 或 4 部电影的平均值

嗯,我在你的流派里加了一个IDtable,不然我做不了这个作品。于是,变成了:

CREATE TABLE `genre` (
  `genreId` INT,
  `code` INT NOT NULL AUTO_INCREMENT,
  `genre` VARCHAR(20) NOT NULL,
  PRIMARY KEY  (`code`)
);

而且我必须假设所有类型都在此 table 中定义。我将以此 table 作为基础,并且正如您所建议的那样使用子查询:

SELECT
  genre.code,
  genre.genre,
  (<my sub select comes here>)
FROM
  genre;

这基本上为您提供了所有流派的列表。现在由子查询给出每种类型电影的平均费率。该子查询可能如下所示:

SELECT AVG(movieRating.rating)
FROM movieRating
JOIN movie ON movie.movieId = movieRating.movieId  
JOIN movieGenre ON movieGenre.movieId = M.movieId  
WHERE movieGenre.genreId = genre.genreId;

我把它保持得非常简单。我们从我们想要的平均值开始,从 movieRating 开始,通过 moviemovieGenre table 到达最后 [=] 中的 genreId 36=]。注意来自主查询的 genre.genreId 。我们按 genreId.

隐式分组

现在您可以将此子查询放在主查询中,但这仍然不能解决没有评级来取平均值的情况。它会导致 NULL,意思是:没有结果。这几乎已经足够好了,但您可以在其周围放置一个 IFNULL() 以获得正确的零结果。

整个查询将变成这样:

SELECT
  genre.code,
  genre.genre,
  IFNULL((SELECT AVG(movieRating.rating)
          FROM movieRating
          JOIN movie ON movie.movieId = movieRating.movieId  
          JOIN movieGenre ON movieGenre.movieId = M.movieId  
          WHERE movieGenre.genreId = genre.genreId), 0) AS Average
FROM
  genre;

我不能保证这会起作用,因为我无法对其进行测试,而编写查询时测试就是一切。