Por que meu script SQL seleciona muitas saídas (CS50 pset7 sql.13)?

Aug 19 2020

Atualmente, estou trabalhando em pset7 em cs50 e pensei ter selecionado o número correto de valores especificados, mas meu script está gerando 349 linhas em vez das 176 que a chave de resposta possui.

"No 13.sql, escreva uma consulta SQL para listar os nomes de todas as pessoas que estrelaram um filme no qual Kevin Bacon também estrelou. Sua consulta deve gerar uma tabela com uma única coluna para o nome de cada pessoa. Pode haver vários pessoas chamadas Kevin Bacon no banco de dados. Certifique-se de selecionar apenas o Kevin Bacon nascido em 1958. O próprio Kevin Bacon não deve ser incluído na lista resultante."

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)
            );

MEU ROTEIRO

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"

Existem alguns erros lógicos neste script? Minha lógica era:

  • Selecione todos os filmes em que Kevin Bacon estrela (selecionar aninhado)
  • Selecione nomes de estrelas (principal SELECT) que aparecem em qualquer um desses filmes de Kevin Bacon, exceto o próprio Kevin Bacon.

Respostas

Isolated Aug 19 2020 at 02:49

Algo assim funcionaria no postgres. Pode precisar se adaptar ao seu banco de dados.

    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'