这是数据集:
电影(mID,标题,年份,导演)英语:有一部带ID的电影 号码mID,标题,发行年份和导演。
审稿人(rID,姓名)英语:ID号为rID的审稿人有一个 某个名字。
评级(rID,mID,stars,ratingDate)英语:评论员rID给出 电影mID在某个评级日期评分(1-5)。
以下是问题:查找所有没有评分的电影的标题。
我的回答:(返回空集)
select title from movie,rating where movie.mid=rating.mid and stars is null
正确答案:
select title
from movie
left join rating using (mID)
where stars is null
我不确定我的加入有什么问题?提前谢谢!
答案 0 :(得分:1)
您在电影和评级之间进行完全交叉连接。这意味着您的结果集最初包含所有可能的(电影,评级)组合。
您需要movie.mid = rating.mid
。这会将您的结果集限制为只有那些(电影,评级)对,其中评级实际上是与其配对的电影。
但想象一部没有评级的电影。它永远不会出现在评级表中,因此movie.mid = rating.mid
也永远不会成立。由于这种情况永远不会成立,所有没有评级的电影都将从where子句的结果集中删除。
正确答案使用left join
。连接匹配影片中的所有行以及通过连接条件的评级中的所有行(在这种情况下,mID
需要相等)。到目前为止,这在语义上和你写的一样。但是left
部分开始发挥作用:这意味着对于通过连接条件的评级中没有任何行的任何电影行,无论如何都会包含电影行(一次) )具有评级表列的所有NULL
值。然后,stars is null
条件仅采用left
效果生成的行。 (请注意,只有在评级表中stars
不允许为空时,where子句才能正常工作。)
答案 1 :(得分:0)
如果电影没有评分,rating.mid
将为空,因此movie.mid=rating.mid
将为false。
如果某部电影确实有评分,那么movie.mid=rating.mid
会有效,但(推测)stars is null
会有误。
所以你的状况永远不会得到满足。
您发布的正确答案有效,因为join
条件与where
条件是分开的。首先将movies
表连接到rating
表,然后将结果过滤到没有连接到它们的行。