How to list all the people who have worked with 'Art Garfunkel'?
I have 3 tables actor
, movie
, casting
. I have to find the people who have worked with actor "ART Garfunkel".
I have solution but I am not able to understand how the following query works.
**movie** **actor** **casting**
id id movieid
title name actorid
yr ord
director
budget
gross
SELECT a.name
FROM (SELECT movie.*
FROM movie
JOIN casting
ON casting.movieid = movie.id
JOIN actor
ON actor.id = casting.actorid
WHERE actor.name = 'Art Garfunkel') AS m
JOIN (SELECT actor.*, casting.movieid
FROM actor
JOIN casting
ON casting.actorid = actor.id
WHERE actor.name != 'Art Garfunkel') as a
ON m.id = a.movieid;
one more solution:
SELECT actor.name FROM casting
JOIN movie ON movie.id=casting.movieid
JOIN actor ON actor.id=casting.actorid
WHERE actor.name !='Art Garfunkel'
AND
movie.id IN(SELECT movie.id FROM casting
JOIN movie ON movie.id=casting.movieid
JOIN actor ON actor.id=casting.actorid
WHERE actor.name='Art Garfunkel')
Easy Solution:
SELECT distinct actor.name
FROM movie
JOIN casting
ON casting.movieid = movie.id
JOIN actor
ON actor.id = casting.actorid
where movie.id in (select movieid from casting join actor on id =actorid where
actor.name = 'Art Garfunkel') and actor.name <> 'Art Garfunkel'
Here's a simplified version that does the same thing:
select actor.name
from (
select movieid from casting
join actor on actor.id = casting.actorid
and actor.name = 'Art Garfunkel'
) ag_movies
join casting on ag_movies.movieid = casting.movieid
join actor on actor.id = casting.actorid
and actor.name != 'Art Garfunkel'
Yours follows roughly the same steps:
- Get the movieid for all movies Art Garfunkel was in.
- Find the cast lists for all those movies.
- Get the artist names from the cast lists that are not Art Garfunkel.
The casting table is a cross-lookup table which allows many actors to act in many movies. Through the casting table we have to find all the movies Art was in and then reverse that to find the other actors in those movies.
The joins mean the result will only contain rows from both tables which match the join criteria. So on actor.id = casting.actorid and actor.name = 'Art Garfunkel'
connects the tables by the matching IDs but limits the results to only those IDs where the actor name is Art's. The join as used in these queries means the same as intersection from set theory.
The sub-select inside the parenthesis creates a temporary table (named ag_movies in this example) that can be used by the parent query just like any other table.
Here is a solution for MySQL:
SELECT name FROM actor JOIN casting ON actor.id = actorid JOIN movie ON movie.id = movieid WHERE movie.id IN (
SELECT movieid FROM casting
WHERE actorid IN (SELECT id FROM actor WHERE name = 'Art Garfunkel')
) AND actor.name != 'Art Garfunkel';