#sql #cs50
#sql #cs50
Вопрос:
В настоящее время я работаю над pset7 в cs50, и я думал, что выбрал правильное количество указанных значений, но мой скрипт выводит 349 строк вместо 176, которые есть в ключе ответа.
«В 13.sql напишите SQL-запрос, чтобы перечислить имена всех людей, которые снимались в фильме, в котором также снялся Кевин Бэкон. Ваш запрос должен вывести таблицу с одним столбцом для имени каждого пользователя. В базе данных может быть несколько человек с именем Кевин Бэкон. Обязательно выберите только Кевина Бейкона, родившегося в 1958 году. Сам Кевин Бэкон не должен быть включен в результирующий список.»
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"
Есть ли какие-то логические ошибки в этом скрипте? Моя логика была:
- Выберите все фильмы, в которых снимается Кевин Бэкон (вложенный ВЫБОР)
- Выберите имена звезд (основной ВЫБОР), которые появляются в любом из этих фильмов Кевина Бэкона, кроме самого Кевина Бэкона.
Комментарии:
1. Прежде всего, ваш внутренний запрос должен выбрать
movies.id
, а неtitle
, посколькуid
он уникален (хотяtitle
может и не быть) и посколькуid
этого достаточно, чтобы узнать, о каком фильме идет речь. Затем вы проверяете,WHERE movie_id IN (...)
и, более того, вам не нужно будет присоединятьсяmovies
во внешнем запросе, потому что у вас уже естьmovie_id
из joiningstars
2. Спасибо за помощь! Если кто-нибудь также использует это для справки, обратите внимание, что когда Alex заявил об использовании,
movie_id
вы должны указать, из какой таблицы вы извлекаете идентификатор, потому чтоmovie_id
он находится в нескольких таблицах. SQL не знает, какой из них вы пытаетесь использовать. В моем случае он использовал…WHERE stars.movie_id IN (
Еще раз спасибо!3. Так ли это? Если ваш внешний запрос
SELECT DISTINCT name FROM people INNER JOIN stars ON people.id = stars.person_id WHERE ...
, тоmovie_id
поступает только изstars
, так что никакой двусмысленности нет.
Ответ №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'