Как мне вывести первое значение из запроса трехсторонней объединенной таблицы?
Тьфу хорошо, я ужасен в объяснении вещей, поэтому сначала я просто дам вам цитаты и ссылки:
Задача 4b (возле дна):
4b. Укажите название фильма и главного актера всех фильмов "Джули Эндрюс".
фильм (id, название, год, оценка, голоса, режиссер)
актер (имя, имя)
кастинг (movieid, actorid, ord)
(Примечание: movie.id = casting.movieid, actor.id = casting.actorid)
Мой ответ (не работает):
SELECT title, name
FROM casting JOIN movie
ON casting.movieid = movie.id
JOIN actor
ON casting.actorid = actor.id
WHERE name = 'Julie Andrews'
AND ord = 1
Проблема здесь в том, что он хочет получить список главных актеров фильмов с "Джули Эндрюс" в качестве актера (который не обязательно является ведущим актером), но все, что я делаю со своим ответом, - это получение фильмов, где она играет главную роль. (ord = 1).
Как мне указать список главных актеров, не говоря о "Джули Эндрюс"? Я подозреваю, что должен что-то сделать с GROUP BY, но я не могу понять, что в данный момент...
Редактировать: мне нужно использовать вложенный SELECT?
9 ответов
Есть замечательные способы сделать это с помощью подзапросов, но, похоже, что в этом уроке вы работаете только с JOIN. Ниже описано, как вы будете делать это только с JOIN:
SELECT
movie.title,
a2.name
FROM
actor AS a1
JOIN casting AS c1 ON (a1.id = c1.actorid)
JOIN movie ON (c1.movieid = movie.id)
JOIN casting AS c2 ON (movie.id = c2.movieid)
JOIN actor AS a2 ON (c2.actorid = a2.id)
WHERE
a1.name = 'Julie Andrews'
AND c2.ord = 1
РЕДАКТИРОВАТЬ (более описательный):
Это даст нам таблицу, содержащую все фильмы, в которых принимала участие Джули Эндрюс. Я присваиваю псевдонимы актёрам и кастам как a1 и c1 соответственно, потому что теперь, когда мы нашли список фильмов, нам нужно будет повернуться и соответствовать это снова против литейного стола.
SELECT
movie.*
FROM
actor a1
JOIN casting c1 ON (a1.id = c1.actorid)
JOIN movie ON (c1.movieid = movie.id)
WHERE
a1.name = 'Julie Andrews'
Теперь, когда у нас есть список всех фильмов, которые она сыграла, нам нужно соединить это с таблицей ролей (как c2) и со списком актеров (как a2), чтобы получить список главных ролей для этих фильмов:
SELECT
movie.title, -- we'll keep the movie title from our last query
a2.name -- and select the actor's name (from a2, which is defined below)
FROM
actor a1 -- \
JOIN casting AS c1 ON (a1.id = c1.actorid) -- )- no changes here
JOIN movie ON (c1.movieid = movie.id) -- /
JOIN casting AS c2 ON (movie.id = c2.movieid) -- join list of JA movies to the cast
JOIN actor AS a2 ON (c2.actorid = a2.id) -- join cast of JA movies to the actors
WHERE
a1.name = 'Julie Andrews' -- no changes
AND c2.ord = 1 -- only select the star of the JA film
Изменить: в псевдониме ключевое слово "AS" не является обязательным. Я вставил его выше, чтобы сделать запрос более понятным
Вы хотите сопоставить фильмы с двумя потенциально отдельными строками в casting
Таблица: один ряд, где Джули Эндрюс является актером, а второй ряд, который может быть или не быть Джули Эндрюс, но который является ведущим актером фильма.
Джули <---> снялась в <---> фильме <---> в главной роли <---> главный актер
Так что вам нужно присоединиться к casting
стол дважды.
SELECT m.title, lead.name
FROM actor AS julie
JOIN casting AS c1 ON (julie.id = c1.actorid)
JOIN movie AS m ON (c1.movieid = m.id)
JOIN casting AS c2 ON (m.id = c2.movieid)
JOIN actor AS lead ON (c2.actorid = lead.id)
WHERE julie.name = 'Julie Andrews'
AND c2.ord = 1;
Помните, что "псевдонимы таблиц" ссылаются на потенциально разные строки, даже если они являются псевдонимами одной и той же таблицы.
SELECT title, name
FROM casting JOIN movie
ON casting.movieid = movie.id
JOIN actor
ON casting.actorid = actor.id
WHERE ord = 1
and casting.movieid in
(select movieid
from casting
join actor
on actor.id = casting.actorid
where actor.name = 'Julie Andrews')
Кстати, это был ответ, размещенный на сайте (я только что узнал об этом):
SELECT title, name
FROM movie, casting, actor
WHERE movieid=movie.id
AND actorid=actor.id
AND ord=1
AND movieid IN
(SELECT movieid FROM casting, actor
WHERE actorid=actor.id
AND name='Julie Andrews')
Пойди разберись.:П
SELECT title , name
FROM movie JOIN casting ON (casting.movieid=movie.id) JOIN actor ON (actor.id=actorid)
WHERE (movieid IN (SELECT movieid
FROM casting JOIN actor ON (actor.id=actorid)
WHERE name = 'Julie Andrews')) AND (ord=1)
select title, name from movie join casting on movie.id=movieid
join actor on actor.id=actorid
where ord=1 and movieid in (select movieid from actor join casting
on actor.id=actorid
where name='julie andrews' and (ord=1 or ord<>1))group by title, name
Делимся простым ответом на этот
select title, name from movie
join casting on movie.id=movieid
join actor on actor.id=actorid where ord=1 and movie.id in (select movie.id from movie
join casting on movie.id=movieid
join actor on actor.id=actorid where name='Julie Andrews')
I ve done simply like this
select distinct title,name from
(select movie.* from movie
inner join casting on (movie.id = casting.movieid)
inner join actor on (casting.actorid = actor.id)
where actor.name = 'Julie Andrews' ) as moviesFromJulie
inner join casting on (moviesFromJulie.id = casting.movieid)
inner join actor on (casting.actorid = actor.id)
where ord = 1
Восстановить все фильмы, в которых играла Джули Эндрюс, затем для этих фильмов восстановить все фильмы и актеров для них с порядковым номером = 1 и отличаться для уникальных результатов
Ответ @Bill Karwin хорош для направления. Однако в результате выясняется, что название некоторых фильмов появлялось более одного раза. Поэтому нам нужно добавить функцию DISTINCT перед заголовком в строке SELECT.
SELECT DISTINCT m.title, lead.name
И если вы хотите более быстрый ответ, вы также можете написать код таким образом.
SELECT DISTINCT m.title, lead.name
FROM actor AS julie
JOIN casting AS c1 ON (julie.id = c1.actorid AND julie.name = 'Julie Andrews')
JOIN movie AS m ON (c1.movieid = m.id)
JOIN casting AS c2 ON (m.id = c2.movieid)
JOIN actor AS lead ON (c2.actorid = lead.id)
WHERE c2.ord = 1;