我需要创建选择下一个的选择:
我有三张桌子:演员,工作室和电影。演员和电影有多对多,工作室和电影有多对多的关系。演员和工作室没有关系。 Films_actors表还有字段' honorarium'。
所以我可以选择工作室,电影和酬金
SELECT studios.title, films.title, films_actors.honorarium
FROM studios
JOIN studios_films ON studios.id = studios_films.studio_id
JOIN films ON films.id = studios_films.film_id
JOIN films_actors ON films.id = films_actors.film_id
下一步(http://www.sqlfiddle.com/#!2/17ff2):
转储MySQL数据库CREATE TABLE IF NOT EXISTS `actors` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`surname` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`birthday` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `studios` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`founded` year(4) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `studios_films` (
`studio_id` int(11) NOT NULL,
`film_id` int(11) NOT NULL,
KEY `studio_id` (`studio_id`),
KEY `film_id` (`film_id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `films` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`director` varchar(255) DEFAULT NULL,
`created` year(4) DEFAULT NULL,
`budget` decimal(12,2) DEFAULT NULL,
`box_office` decimal(13,2) DEFAULT NULL,
`duration` time DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `films_actors` (
`film_id` int(11) NOT NULL,
`actor_id` int(11) NOT NULL DEFAULT '0',
`honorarium` decimal(10,0) DEFAULT NULL,
PRIMARY KEY (`film_id`,`actor_id`),
KEY `actor_id` (`actor_id`)
) ENGINE=InnoDB;
ALTER TABLE `studios_films`
ADD FOREIGN KEY (`studio_id`) REFERENCES `studios` (`id`),
ADD FOREIGN KEY (`film_id`) REFERENCES `films` (`id`);
ALTER TABLE `films_actors`
ADD FOREIGN KEY (`film_id`) REFERENCES `films` (`id`),
ADD FOREIGN KEY (`actor_id`) REFERENCES `actors` (`id`);
感谢您的帮助!
答案 0 :(得分:1)
如果没有样本数据,这很难验证,但我建议你只需要一步一步,这就是我将如何帮助回答你的问题。第一部分很简单,我希望你至少可以选择一个工作室头衔。
对于第二个,您可以在酬金列上使用SUM()函数,并按工作室ID分组以获得每个的总和。您可以使用WHERE子句来确保电影日期在过去10年内(这是我能找到的唯一日期字段,所以我认为这是您需要的。)看起来像这样:
SELECT s.title, SUM(fa.honorarium) AS totalHonorarium
FROM studios s
JOIN studios_films sf ON sf.studio_id = s.id
JOIN films f ON f.id = sf.film_id
JOIN films_actors fa ON fa.film_id = f.id
WHERE f.created >= (SUBDATE(CURDATE(), INTERVAL 10 YEAR))
GROUP BY s.id;
对于下一部分,你的问题中有些含糊不清。您想要所有工作室的平均酬金金额,还是每个工作室的平均金额?您还没有指定“过去十年”,这是其他所有用途。我收到你的回复后,我会编辑这个答案。
要获得工作室在过去10年中创建的电影数量,您只需调整上述查询即可包含COUNT()函数。在这里,您想要为每个studio_id计算不同的film_ids。所以试试这个:
SELECT s.title, SUM(fa.honorarium) AS totalHonorarium, COUNT(DISTINCT f.id) AS totalFilms
FROM studios s
JOIN studios_films sf ON sf.studio_id = s.id
JOIN films f ON f.id = sf.film_id
JOIN films_actors fa ON fa.film_id = f.id
WHERE f.created >= (SUBDATE(CURDATE(), INTERVAL 10 YEAR))
GROUP BY s.id;
最后,为了获得每个工作室的每部电影的酬金(这是我理解你的问题),你需要另一个查询,因为你的分组将会改变。看起来应该是这样的:
SELECT s.title, f.id, SUM(fa.honorarium) AS totalHonorariumForFilm
FROM studios s
JOIN studios_films sf ON sf.studio_id = s.id
JOIN films f ON f.id = sf.film_id
JOIN films_actors fa ON fa.film_id = f.id
WHERE f.created >= (SUBDATE(CURDATE(), INTERVAL 10 YEAR))
GROUP BY s.id, f.id;
对于这些示例,这里有一个SQL Fiddle,其中包含了一些虚拟数据。如果您有任何问题,请告诉我,如果您仍然无法获得平均酬金,请向我解释您的需求,我可以帮助您解决问题。
修改强>
您还可以将外键用于create table语句,而不是更改表。这有助于避免一些插入问题。我做了一些建议的修改here。
编辑2
关于编辑,您可以使用与第一个查询相同的连接,并实现一些各种聚合函数以获取所需的值。由于每个工作室仍然可以获得这些值,因此分组保持不变。试试这个:
SELECT s.title, COUNT(DISTINCT f.id) AS totalFilms, COUNT(fa.film_id) AS amountOfHonorarium, SUM(fa.honorarium) AS totalHonorarium, AVG(fa.honorarium) AS averageHonorarium
FROM studios s
JOIN studios_films sf ON sf.studio_id = s.id
JOIN films f ON f.id = sf.film_id
JOIN films_actors fa ON fa.film_id = f.id
WHERE f.created >= (SUBDATE(CURDATE(), INTERVAL 10 YEAR))
GROUP BY s.id;
这里有SQL Fiddle。就每部电影的酬金而言,我认为你可以通过电影获得电影片名和酬金和小组的总和,如下:
SELECT f.title, SUM(fa.honorarium) AS honorariumForFilm
FROM films f
JOIN films_actors fa ON fa.film_id = f.id
GROUP BY f.id;
如果这会产生更好的结果,请告诉我。如果仍然存在混淆,我会继续提供帮助。