【问题标题】:Why does my SQL script select too many outputs (CS50 pset7 sql.13)?为什么我的 SQL 脚本选择了太多的输出 (CS50 pset7 sql.13)?
【发布时间】:2020-08-18 19:19:27
【问题描述】:

我目前正在使用 cs50 中的 pset7,我认为我选择了正确数量的指定值,但我的脚本输出 349 行而不是答案键的 176 行。

“在 13.sql 中,编写一个 SQL 查询来列出所有出演过凯文·培根 (Kevin Bacon) 也出演过的电影的人的姓名。 您的查询应输出一个表,其中包含每个人的姓名的单列。 数据库中可能有多个名为 Kevin Bacon 的人。一定要选1958年出生的凯文培根。 凯文培根本人不应该包含在结果列表中。”

CS50 pset7 sql.13

sqlite> .schema
CREATE TABLE movies (
                    id INTEGER,
                    title TEXT NOT NULL,
                    year NUMERIC,
                    PRIMARY KEY(id)
                );
CREATE TABLE stars (
                movie_id INTEGER NOT NULL,
                person_id INTEGER NOT NULL,
                FOREIGN KEY(movie_id) REFERENCES movies(id),
                FOREIGN KEY(person_id) REFERENCES people(id)
            );
CREATE TABLE directors (
                movie_id INTEGER NOT NULL,
                person_id INTEGER NOT NULL,
                FOREIGN KEY(movie_id) REFERENCES movies(id),
                FOREIGN KEY(person_id) REFERENCES people(id)
            );
CREATE TABLE ratings (
                movie_id INTEGER NOT NULL,
                rating REAL NOT NULL,
                votes INTEGER NOT NULL,
                FOREIGN KEY(movie_id) REFERENCES movies(id)
            );
CREATE TABLE people (
                id INTEGER,
                name TEXT NOT NULL,
                birth NUMERIC,
                PRIMARY KEY(id)
            );

我的脚本

SELECT DISTINCT name

FROM 
    people
    INNER JOIN  stars ON people.id = stars.person_id
    INNER JOIN movies ON movies.id = stars.movie_id

WHERE movies.title IN (

SELECT
    title
    
From
    movies
    INNER JOIN stars ON movies.id = stars.movie_id
    INNER JOIN people ON stars.person_id= people.id
    
WHERE 
    people.name = "Kevin Bacon"
    AND
    people.birth = "1958"
    )
    
EXCEPT SELECT name FROM people WHERE people.name = "Kevin Bacon"

此脚本中是否存在一些逻辑错误?我的逻辑是:

  • 选择 Kevin Bacon 主演的所有电影(嵌套选择)
  • 选择出现在任何这些凯文培根电影中的明星的名字(主要选择),凯文培根本人除外。

【问题讨论】:

  • 首先,您的内部查询应该选择movies.id,而不是title,因为id 是唯一的(而title 可能不是)并且因为id 足以知道这是哪部电影。然后你检查WHERE movie_id IN (...),而且你不需要在外部查询中加入movies,因为你已经有movie_id加入stars
  • 感谢您的帮助!如果有人也使用它来寻求帮助,请注意,当 Alex 声明使用 movie_id 时,您必须指定要从哪个表中提取 id,因为在多个表中都可以找到 movie_id。 SQL 不知道您尝试使用哪一个。就我而言,它正在使用... WHERE stars.movie_id IN ( 再次感谢!
  • 是吗?如果您的外部查询是SELECT DISTINCT name FROM people INNER JOIN stars ON people.id = stars.person_id WHERE ...,那么movie_id 仅来自stars,因此没有歧义。

标签: sql cs50


【解决方案1】:

这样的东西可以在 postgres 中使用。可能需要适应您的数据库。

    select name
    from (
        with kb_movies as
            (select distinct movies.id as kb_movie_id
            from movies
            join stars 
                on stars.movie_id = movies.id
            join people 
                on people.id = stars.people_id
            where people.name = 'Kevin Bacon'
            and people.birth = '1958' --or 1958
            )
            select distinct people.name
            from people
            join stars 
                on stars.people_id = people.id
            join movies 
                on movies.id = stars.movie_id
            join kb_movies 
                on kb_movie_id = movies.id
        )z
    where name <> 'Kevin Bacon'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-06
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多