Mysql从存储在3个表中的事物中选择一列的平均值
Mysql Selecting the average value of a column from things that are stored in 3 tables
我对数据库还很陌生,刚开始使用 mysql。
我有 4 个表(movie
、genre
、movieGenre
和 movieRating
):
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
开始,通过 movie
和 movieGenre
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;
我不能保证这会起作用,因为我无法对其进行测试,而编写查询时测试就是一切。
我对数据库还很陌生,刚开始使用 mysql。
我有 4 个表(movie
、genre
、movieGenre
和 movieRating
):
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
开始,通过 movie
和 movieGenre
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;
我不能保证这会起作用,因为我无法对其进行测试,而编写查询时测试就是一切。