【问题标题】:Why is this SQL query not working? CS50 Pset7 - movies为什么这个 SQL 查询不起作用? CS50 Pset7 - 电影
【发布时间】:2020-01-09 12:36:15
【问题描述】:

我目前正在处理这个https://cs50.harvard.edu/x/2020/psets/7/movies/ 并尝试完成 9.sql。

有一个名为“movies”的数据库,其中包含表格:电影(列:id、title、year)、people(id、name、birth)和 stars(movie_id、person_id)。

任务是:

编写一个 SQL 查询来列出所有在 2004年上映的电影,按出生年份排序。它应该返回 18,013 名字。

到目前为止,这就是我所做的:

SELECT count(distinct name) 
from people
join stars on stars.person_id = people.id
join movies on stars.movie_id = movies.id
WHERE year = 2004;

但是,这只会返回 17,965 的计数...

谁能明白为什么会这样?

【问题讨论】:

  • 我们如何验证结果?也许这个数字可以反映出一些演员当年拍了几部电影?
  • 常春藤联盟大学使用 sqlite 并引用 w3schools...我摇头。
  • 可以从这里下载数据库:cdn.cs50.net/2019/fall/psets/7/movies/movies.zip 我也试过不带“distinct”,但这又给了太多名字...
  • 我已经验证了你的号码。有趣的问题。
  • 如果你count(distinct person_id),那么你将得到18013。name不是唯一的,这是合理的。不合理的是考试中的指令说你应该只列出name

标签: sql sqlite cs50


【解决方案1】:

如果你count(distinct person_id),那么你会得到18013。名字不唯一是合理的。不合理的是考试中的指令说你应该只列出名字。

正确区分名称的一种方法是执行以下操作:

SELECT p.name
from people p
where p.id in (
select distinct s.person_id
from stars s join movies m on s.movie_id = m.id
WHERE m.year = 2004)

如果你这样做,那么由于in 运算符的定义,你甚至不需要distinct。但无论如何,您可能会得到相同的执行计划。

在我看来,如果 p.name 属于另一个人,则可以多次列出它。如果规则以这些词开头,那么您编写的查询就可以了:

如果一个人的名字...

而不是这些词:

如果一个人...

这让我想起了C. J. Date 某天在课堂上所做的一件事。他在投影仪上贴了一层箔纸,将烟斗的图像投射到墙上。然后他问:这是什么?

  • 一个烟斗,一个人说(可能是我)。
  • 另一个人说的管道图像。
  • 最后,有人说墙上投影的管道图像。

既然是数据库类而不是物理类,就没人敢当smart-a**。

【讨论】:

  • 我在使用in 时要小心一点,因为它有时会影响性能。 1800 条记录可能不会太可怕,但对于更大规模的 SQL 事务需要注意。对于更多的记录,我发现exists 效果更好。
  • @user2366842 如果你有一个好的执行计划,in 没有任何问题,这要求你测试代码的性能和准确性。我们都应该使用可接受的数据来测试代码的性能。
  • 啊,好吧,所以在 2004 年有一些同名(但 person_id 不同)的人出演了电影,我现在明白为什么它不起作用了。谢谢!
猜你喜欢
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-04
相关资源
最近更新 更多