电影
2026 年的变更:5.sql 现在要求匹配以 “Harry Potter and the “ 开头的电影(不仅仅是 “Harry Potter”)。9.sql 现在要求输出两列(每个人的 ID 和名称),而不仅仅是名称。如果你在 2026 年之前开始做这个问题,请务必相应地更新你的查询!

要解决的问题
提供给你的是一个名为 movies.db 的 SQLite 数据库,该数据库存储来自 IMDb 的关于电影、导演和主演以及其评分的数据。编写 SQL 查询来回答关于此电影数据库的问题。
演示
入门
对于这个问题,你将使用 CS50 工作人员提供给你的一个数据库。
下载分发代码
登录 cs50.dev,点击你的终端窗口,然后只执行 cd。你应该会发现你的终端窗口的提示符类似于下面所示:
$
接下来执行
wget https://cdn.cs50.net/2026/x/psets/7/movies.zip
以便将一个名为 movies.zip 的 ZIP 文件下载到你的 codespace 中。
然后执行
unzip movies.zip
来创建一个名为 movies 的文件夹。你不再需要这个 ZIP 文件了,所以你可以执行
rm movies.zip
然后在提示符下回复”y”并按回车键来删除你下载的 ZIP 文件。
现在输入
cd movies
然后按回车键来将自己移入(即打开)该目录。你的提示符现在应该类似于下面所示。
movies/ $
只执行 ls,你应该看到 13 个 .sql 文件,以及 movies.db。
如果遇到任何问题,再按照这些步骤试一次,看看你能不能找出哪里出错了!
规格说明
对于以下每个问题,你应编写一个单一的 SQL 查询,输出每个问题指定的结果。你的响应必须采用单个 SQL 查询的形式,尽管你可以在查询中嵌套其他查询。你不应假设任何特定电影或人物的 id 是什么:即使任何特定电影或人物的 id 不同,你的查询也应该是准确的。最后,每个查询应仅返回回答问题所需的数据:例如,如果问题只要求你输出电影的名称,那么你的查询不应同时输出每部电影的发行年份。
欢迎你将查询结果与 IMDb 本身进行核对,但要注意网站上的评分可能与 movies.db 中的评分不同,因为自从我们下载数据以来可能已经有更多投票!
- 在
1.sql中,编写一个 SQL 查询来列出 2008 年发行的所有电影的标题。- 你的查询应输出一个表格,其中包含一列,为每部电影的标题。
- 在
2.sql中,编写一个 SQL 查询来确定 Emma Stone 的出生年份。- 你的查询应输出一个表格,其中包含一列和一行(不计表头),包含 Emma Stone 的出生年份。
- 你可以假设数据库中只有一个人名为 Emma Stone。
- 在
3.sql中,编写一个 SQL 查询来列出 2018 年及之后发行的所有电影的标题,按字母顺序排列。- 你的查询应输出一个表格,其中包含一列,为每部电影的标题。
- 2018 年发行的电影应包括在内,发行日期在未来的电影也应包括在内。
- 在
4.sql中,编写一个 SQL 查询来确定 IMDb 评分为 10.0 的电影数量。- 你的查询应输出一个表格,其中包含一列和一行(不计表头),包含评分为 10.0 的电影数量。
- 在
5.sql中,编写一个 SQL 查询来列出所有哈利波特电影的标题和发行年份,按时间顺序排列。- 你的查询应输出一个表格,其中包含两列,一列为每部电影的标题,一列为每部电影的发行年份。
- 你可以假设所有哈利波特电影的标题将以 “Harry Potter and the “ 开头,并且如果电影标题以 “Harry Potter and the “ 开头,那么它就是一部哈利波特电影。
- 在
6.sql中,编写一个 SQL 查询来确定 2012 年发行的所有电影的平均评分。- 你的查询应输出一个表格,其中包含一列和一行(不计表头),包含平均评分。
- 在
7.sql中,编写一个 SQL 查询来列出 2010 年发行的所有电影及其评分,按评分降序排列。对于评分相同的电影,按标题字母顺序排列。- 你的查询应输出一个表格,其中包含两列,一列为每部电影的标题,一列为每部电影的评分。
- 没有评分的电影不应包含在结果中。
- 在
8.sql中,编写一个 SQL 查询来列出所有在 Toy Story 中出演的人的名称。- 你的查询应输出一个表格,其中包含一列,为每个人的名称。
- 你可以假设数据库中只有一部电影标题为 Toy Story。
- 在
9.sql中,编写一个 SQL 查询来列出所有在 2004 年发行的电影中出演的人的 ID 和名称,按出生年份排序。- 你的查询应输出一个表格,其中包含两列:一列为每个人的 ID,一列为每个人的名称。
- 出生年份相同的人可以以任何顺序列出。
- 无需担心没有列出出生年份的人,只要那些有出生年份的人按顺序列出即可。
- 如果一个人在 2004 年出现在多于一部电影中,他们在你的结果中只应出现一次。
- 在
10.sql中,编写一个 SQL 查询来列出所有导演过评分至少为 9.0 的电影的人的名称。- 你的查询应输出一个表格,其中包含一列,为每个人的名称。
- 如果一个人导演了多于一部评分至少为 9.0 的电影,他们在你的结果中只应出现一次。
- 在
11.sql中,编写一个 SQL 查询来列出 Chadwick Boseman 出演的五部评分最高的电影标题(按顺序),从评分最高的开始。- 你的查询应输出一个表格,其中包含一列,为每部电影的标题。
- 你可以假设数据库中只有一个人名为 Chadwick Boseman。
- 在
12.sql中,编写一个 SQL 查询来列出 Bradley Cooper 和 Jennifer Lawrence 都出演的所有电影的标题。- 你的查询应输出一个表格,其中包含一列,为每部电影的标题。
- 你可以假设数据库中只有一个人名为 Bradley Cooper。
- 你可以假设数据库中只有一个人名为 Jennifer Lawrence。
- 在
13.sql中,编写一个 SQL 查询来列出所有在 Kevin Bacon 也出演的电影中出演的人的名称。- 你的查询应输出一个表格,其中包含一列,为每个人的名称。
- 数据库中可能有多个名为 Kevin Bacon 的人。请务必只选择 1958 年出生的 Kevin Bacon。
- Kevin Bacon 本人不应包含在结果列表中。
提示
理解 movies.db 的架构
每当接触一个新数据库时,最好首先理解它的架构。在终端窗口中,运行 sqlite3 movies.db,这样你就可以开始在数据库上执行查询了。
首先,当 sqlite3 提示你提供查询时,输入 .schema 并按回车键。这将输出用于生成数据库中每个表的 CREATE TABLE 语句。通过检查这些语句,你可以识别每个表中存在的列。
注意,movies 表有一个唯一标识每部电影的 id 列,以及用于电影 title 和电影发行 year 的列。people 表也有一个 id 列,还有用于每个人 name 和 birth 年份的列。
与此同时,电影评分存储在 ratings 表中。该表的第一列是 movie_id:一个引用 movies 表 id 的外键。行的其余部分包含有关每部电影 rating 的数据以及电影在 IMDb 上收到的 votes 数。
最后,stars 和 directors 表将人物与他们出演或导演的电影匹配起来。(仅包含主要明星和导演。)每个表只有两列:movie_id 和 person_id,分别引用特定的电影和人物。
你面前的挑战是编写 SQL 查询,通过从这些表中的一个或多个中选择数据来回答各种不同问题。
一致地格式化你的查询
请参阅 sqlstyle.guide 了解 SQL 良好风格的指南,尤其是当你的查询变得更加复杂时!
列出 2008 年发行的所有电影的标题
回想一下,你可以使用 SELECT 从数据库中选择一列(或多列),如下例所示:
SELECT column0, column1 FROM table;
其中 column0 是一列的标题,column1 是另一列的标题。
再回想一下,你可以使用 WHERE 关键字后跟条件来过滤查询返回的行。你也可以使用 =、>、< 和其他运算符。
SELECT column FROM table
WHERE condition;
请参阅此 SQL 关键字参考了解一些可能有用的 SQL 语法!
确定 Emma Stone 的出生年份
回想一下,WHERE 子句不仅可以对数字,还可以对字符串评估条件。
列出 2018 年及之后发行的所有电影的标题,按字母顺序排列
尝试将此查询分解为两个步骤。首先,找到 2018 年及之后发行的电影。然后,将这些电影的标题按字母顺序排列。
要找到 2018 年及之后发行的电影,回想一下 SQL 中的条件支持使用许多常见的比较运算符,包括表示”大于或等于”的 >=。根据如何测试检查你的查询是否返回了正确数量的电影。
最后,按标题字母顺序对查询结果进行排序。回想一下 ORDER BY 可以按结果中的某一列对数据进行排序,如下例所示。
...
ORDER BY column;
确定 IMDb 评分为 10.0 的电影数量
注意此问题要求你提供的不是评分为 10.0 的个别电影,而是具有该评分的电影的数量。换句话说,你应该将查询结果收集(”聚合”)为单个数字(行数)。回想一下 SQL 支持一个名为 COUNT 的”聚合函数”,你可以在列上使用它,如下例所示。
SELECT COUNT(column)
FROM table;
列出所有哈利波特电影的标题和发行年份,按时间顺序排列
对于此查询,你可能想使用 SQL 的 LIKE 关键字。回想一下 LIKE 可以使用所谓的”通配符”,如 %,它将匹配任何字符(或字符序列)。
SELECT column0, column1
FROM table
WHERE column1 LIKE pattern;
确定 2012 年发行的所有电影的平均评分
这是另一个你需要聚合数据的查询示例。考虑使用 SQL 的 AVG 聚合函数来计算平均值。
还要考虑,此查询使用了存储在两个独立表中的数据:ratings 和 movies。回想一下——只要一个表有一个与另一个表的列匹配的外键——你就可以使用 SQL 的 JOIN 关键字将两个表组合起来。要使用 JOIN 关键字,你应该指定要连接的表以及用来连接的列。
SELECT column0
FROM table0
JOIN table1 ON table0.column1 = table1.column2
列出 2010 年发行的所有电影及其评分,按评分降序排列
回想一下 ORDER BY 不必总是按升序排序。你可以通过附加 DESC 来指定结果按降序排序。
...
ORDER BY column DESC;
列出在 Toy Story 中出演的所有人的名称
当你看到像这样的更复杂的查询时,最好将其分解为更小的部分。最终,你的查询应得出一个名称列表,如下所示。
-- Select names
SELECT name
FROM people
WHERE ...
但如何最好地得出在 Toy Story 中出演的人的名称呢?考虑一下,仅凭 people 表没有此信息(但 stars 表可能有!)。实际上,stars 表组合了两列,person_id 和 movie_id:任何具有与 Toy Story 的 movie_id 相关联的 person_id 的人都在 Toy Story 中出演过。
-- Select names
SELECT name
FROM people
WHERE ...
-- Select person IDs
SELECT person_id
FROM stars
WHERE movie_id = ...
那么,自然的下一步就是查找 Toy Story 的电影 ID。
-- Select names
SELECT name
FROM people
WHERE ...
-- Select person IDs
SELECT person_id
FROM stars
WHERE movie_id = ...
-- Find Toy Story's ID
SELECT id
FROM movies
WHERE title = 'Toy Story';
当然,你现在已经编写了三个独立的查询。但请注意,某些查询(前两个)通过包含其正下方的查询结果就可以完成。制作依赖”子查询”结果的查询的过程称为”嵌套”查询。这是一个很大的提示,但以下是嵌套上述查询的一种方式!
-- Select names
SELECT name
FROM people
WHERE id IN
(
-- Select person IDs
SELECT person_id
FROM stars
WHERE movie_id = (
-- Select Toy Story's ID
SELECT id
FROM movies
WHERE title = 'Toy Story'
)
);
列出所有在 2004 年发行的电影中出演的人的 ID 和名称,按出生年份排序
注意,这个查询与上一个类似,需要你使用来自多个表的数据。回想一下,你可以在 SQL 中“嵌套”查询,这使你可以将较大的查询分解为较小的查询。也许你可以编写查询来…
- 查找 2004 年发行的电影的 ID
- 查找在这些电影中出演的人的 ID
- 查找具有这些人员 ID 的人的 ID 和名称
然后,尝试嵌套这些查询以得出一个单一查询,该查询返回所有在 2004 年发行的电影中出演的人的 ID 和名称。考虑你如何然后对查询结果进行排序。
作为结束笔记,请记住多个人可以有相同的名称。虽然每个人应该只在你的结果中出现一次,但两个明星有相同的名称并不一定意味着他们是同一个人。
列出所有导演过评分至少为 9.0 的电影的人的名称
注意,这个查询与上一个类似,需要你使用来自多个表的数据。回想一下,你可以在 SQL 中“嵌套”查询,这使你可以将较大的查询分解为较小的查询。也许你可以编写查询来…
- 查找评分至少为 9.0 的电影的 ID
- 查找导演了这些电影的人的 ID
- 查找具有这些人员 ID 的人的名称
然后,尝试嵌套这些查询以得出一个单一查询,该查询返回所有导演过评分至少为 9.0 的电影的人的名称。
列出 Chadwick Boseman 出演的五部评分最高的电影标题(按顺序),从评分最高的开始
注意,这个查询与上一个类似,需要你使用来自多个表的数据。回想一下,你可以在 SQL 中“嵌套”查询,这使你可以将较大的查询分解为较小的查询。也许你可以编写查询来…
- 查找 Chadwick Boseman 的 ID
- 查找与 Chadwick Boseman 的 ID 相关联的电影的 ID
- 查找具有这些电影 ID 的电影标题
然后,尝试嵌套这些查询以得出一个单一查询,该查询返回 Chadwick Boseman 的电影标题。
从那里,你需要确定这些标题的评分,并按评分降序排列这些标题。考虑你如何组合一个相关的表(很可能是 ratings!)并按相关列对结果进行排序。
最后,阅读 SQL 的 LIMIT 关键字,它将返回查询中的前 n 行。
列出 Bradley Cooper 和 Jennifer Lawrence 都出演的所有电影的标题
注意,这个查询与上一个类似,需要你使用来自多个表的数据。回想一下,你可以在 SQL 中“嵌套”查询,这使你可以将较大的查询分解为较小的查询。也许你可以编写查询来…
- 查找 Bradley Cooper 的 ID
- 查找 Jennifer Lawrence 的 ID
- 查找与 Bradley Cooper 的 ID 相关联的电影的 ID
- 查找与 Jennifer Lawrence 的 ID 相关联的电影的 ID
- 从与 两者 Bradley Cooper 和 Jennifer Lawrence 相关联的电影 ID 中查找电影标题
然后,尝试嵌套这些查询以得出一个单一查询,该查询返回 Bradley Cooper 和 Jennifer Lawrence 都出演的电影。
回想一下,你可以在 SQL 中使用 AND 或 OR 构建复合条件。
列出所有在 Kevin Bacon 也出演的电影中出演的人的名称
注意,这个查询与上一个类似,需要你使用来自多个表的数据。回想一下,你可以在 SQL 中“嵌套”查询,这使你可以将较大的查询分解为较小的查询。也许你可以编写查询来…
- 查找 Kevin Bacon 的 ID(1958 年出生的那个!)
- 查找与 Kevin Bacon 的 ID 相关联的电影的 ID
- 查找与这些电影 ID 相关联的人的 ID
- 查找具有这些人员 ID 的人的名称
然后,尝试嵌套这些查询以得出一个单一查询,该查询返回所有在 Kevin Bacon 也出演的电影中出演的人的名称。请记住,你要将 Kevin Bacon 本人从结果中排除!
讲解视频
使用方法
要在 VS Code 中测试你的查询,你可以通过运行以下命令来查询数据库
$ cat filename.sql | sqlite3 movies.db
其中 filename.sql 是包含你的 SQL 查询的文件。
你也可以运行
$ cat filename.sql | sqlite3 movies.db > output.txt
将查询的输出重定向到一个名为 output.txt 的文本文件。(这对于检查你的查询返回了多少行很有用!)
如何测试
虽然 check50 可用于本问题,但我们鼓励你改为对以下每一项自行测试你的代码。你可以运行 sqlite3 movies.db 在数据库上运行额外查询,以确保你的结果是正确的。
如果你使用的是本问题集分发中提供的 movies.db 数据库,你应该发现
- 执行
1.sql会生成一个包含 1 列和 10,647 行的表格。 - 执行
2.sql会生成一个包含 1 列和 1 行的表格。 - 执行
3.sql会生成一个包含 1 列和 154,665 行的表格。 - 执行
4.sql会生成一个包含 1 列和 1 行的表格。 - 执行
5.sql会生成一个包含 2 列和 18 行的表格。 - 执行
6.sql会生成一个包含 1 列和 1 行的表格。 - 执行
7.sql会生成一个包含 2 列和 7,386 行的表格。 - 执行
8.sql会生成一个包含 1 列和 10 行的表格。 - 执行
9.sql会生成一个包含 2 列和 36,219 行的表格。 - 执行
10.sql会生成一个包含 1 列和 4,675 行的表格。 - 执行
11.sql会生成一个包含 1 列和 5 行的表格。 - 执行
12.sql会生成一个包含 1 列和 4 行的表格。 - 执行
13.sql会生成一个包含 1 列和 550 行的表格。
注意,行数不包括仅显示列名的表头行。
如果你的查询返回的行数与预期输出略有不同,请确保你正确处理了重复项!对于要求列出名称列表的查询,任何一个人都不应被列出两次,但两个有相同名称的不同人应该各自被列出。
正确性
check50 cs50/problems/2026/x/movies
如何提交
在终端中执行以下命令提交你的作业,并按提示完成操作。
submit50 cs50/problems/2026/x/movies
致谢
信息由 IMDb (imdb.com) 提供。 经许可使用。