2014-10-30 50 views
0

我的,需要我列出的演员,在电影出现,然后是已经在其他电影与他们的出演演员的转让工作出现了。数据库的图可以在这里查看:http://i.imgur.com/kj8qVgF.pngSQL - 属性列表,与他人

我有一个查询第一部分(获取演员和演员的名字出现在某个电影中)。

SELECT DISTINCT n.name 
FROM cast_info c 
INNER JOIN name n 
ON (n.id = c.person_id) 
INNER JOIN title t 
ON (c.movie_id = t.id) 
CROSS JOIN role_type r 
WHERE (t.title = 'The Movie') AND (r.role = 'actress' OR r.role = 'actor') 

我可以得到一些帮助,帮助我找到在其他电影中与他们一起出演的演员和演员吗?

例子:

Actors in a given movie 'The Movie': Bob, Joe, Billy 
Actors in a different movie 'Another Movie': Joe, Daniel, Frank 
Actors in another different movie 'Third Movie': Billy, Susan, Theodore 

它应该返回丹尼尔·弗兰克,苏珊和西奥多,因为他们至少在一个主演的电影在给定的电影演员之一。

+0

你为什么要使用交叉连接到role_type?为什么不在c.role_id = r.id上使用内部连接row_type? – 2014-10-30 04:52:15

+0

你应该发布一些样本数据和预期输出来澄清你的问题。 – 2014-10-30 04:56:20

+0

我张贴@JaugarChang – 2014-10-30 18:33:41

回答

1

根据你的榜样,你的模式是3NF,所以你可以用微不足道IN来解决,就像你在自然语言描述的问题。

SELECT DISTINCT n.name 
FROM cast_info c 
INNER JOIN name n 
ON (n.id = c.person_id) 
INNER JOIN title t 
ON (c.movie_id = t.id) 
INNER JOIN role_type r 
ON (c.role_id = r.id) 
WHERE (r.role = 'actress' OR r.role = 'actor') -- find the actresses and actors ... 
AND c.movie_id IN   -- starred in at least one movie ... 
    (SELECT movie_id 
    FROM cast_info 
    WHERE id in   -- with one of the actors in the given movie => Bob, Joe, Billy 
     (SELECT cc.id 
     FROM cast_info cc 
     INNER JOIN role_type rr 
     ON (cc.role_id = rr.id) 
     WHERE (rr.role = 'actor') -- only select actors in the given movie 
     AND cc.movie_id in (select id from title where title = 'The Movie') 
     ) 
    ) 
AND c.id NOT IN -- except the actors in the given movie 
     (SELECT cc.id 
     FROM cast_info cc 
     INNER JOIN role_type rr 
     ON (cc.role_id = rr.id) 
     WHERE (rr.role = 'actor') -- only select actors in the given movie 
     AND cc.movie_id in (select id from title where title = 'The Movie') 
     ) 

这种易于自然语言转化为SQL,但使用IN效率不高,你可以用EXISTS转移IN,那将是更有效的。

+0

感谢您的答复!我继续这样做,它似乎工作。但是,在最后两个子查询中,是不是应该检查演员和演员?当我使用它来搜索最后两个WHERE子句中的演员和演员时,我似乎没有得到任何结果。 – 2014-10-31 03:22:03

+0

在你的例子中,你需要Bob,Joe,Billy从给定的电影中获得,并且你说'给定电影中的一个演员',所以我使用'rr.role ='actor''。如果你想要女演员和演员,你可以在女演员中使用rr.role,不要使用r.role ='actress'和r.role ='actor' ,Englisth说'演员和演员'不同,并且不会得到任何结果。 – 2014-10-31 05:11:49

1

所以,我们再次见面。希望我能得到和你最后一个问题一样的帮助。我喜欢你的开始,把它分解成更小的部分。我会和你一样开始 - 让所有演员参与必要的电影。我已经改变了你的查询,通过选择个人id而不是他们的名字,所以我可以保持这个答案更短,更干净。

SELECT c.person_id 
FROM cast_info c 
JOIN title t ON c.movie_id = t.id 
JOIN role_type r ON c.role_id = r.id 
WHERE t.title = 'The Movie' AND (r.role = 'actress' OR r.role = 'actor'); 

*注意,因为一个人不应该在这部电影作为一个演员或女演员不止一次出现,我没有使用不同的在这里,但c.person_id不是唯一的密钥,因此它不会伤害是当然。

然后,我们可以得到所有的电影在他们的演员。我们可以过滤以避免原始表格。

SELECT t.id 
FROM title t 
JOIN cast_info c ON c.movie_id = t.id 
WHERE t.title != 'The Movie' 
    AND c.person_id IN(SELECT c.person_id 
         FROM cast_info c 
         JOIN title t ON c.movie_id = t.id 
         JOIN role_type r ON r.id = c.role_id 
         WHERE t.title = 'The Movie' AND (r.role = 'actress' OR r.role = 'actor')) 

现在我们可以从所有这些电影中拉出所有演员,并排除我们的原始演员。这里是使用不同的人员ID的好主意。这是因为鲍勃可能会出演'电影'。后来,鲍勃和约翰拍了电影,和约翰拍了另一部电影,但我们不想约翰出现两次。

所以,这里是最后的查询:

SELECT DISTINCT c.person_id 
FROM cast_info c 
WHERE c.movie_id IN(SELECT t.id 
       FROM title t 
       JOIN cast_info c ON c.movie_id = t.id 
       WHERE t.title != 'The Movie' 
        AND c.person_id IN(SELECT c.person_id 
             FROM cast_info c 
             JOIN title t ON c.movie_id = t.id 
             JOIN role_type r ON r.id = c.role_id 
             WHERE t.title = 'The Movie' AND (r.role = 'actress' OR r.role = 'actor'))) 
    AND c.person_id NOT IN(SELECT c.person_id 
         FROM cast_info c 
         JOIN title t ON c.movie_id = t.id 
         JOIN role_type r ON r.id = c.role_id 
         WHERE t.title = 'The Movie' AND (r.role = 'actress' OR r.role = 'actor')) 

正如我之前所说,这是很难测试这个没有数据,这是一个很大的表做一个简单的SQL小提琴,所以请尽量这些有点像我写过它们,如果他们不工作,让我知道可能需要调整。

+0

再次您好!我很感激你花时间回复我的问题。我很抱歉问这么多(老实说,我甚至比这更多)!我的老师非常快速地通过SQL,你不会相信在这个任务上也会挣扎的人数。因为没有人完成它,它已经推迟了3次(令人惊讶?)。无论如何,回到主题......我测试了您的查询(在添加像3个末尾括号后),并且它似乎没有返回任何行。如果我能弄清楚错误在哪里,我会告诉你。 – 2014-10-31 03:32:09

+0

哦,上帝很抱歉遗失了包袱。这是我的错。这项任务何时到期? – AdamMc331 2014-10-31 03:33:40

+0

呃......今天午夜。不要过分担心帮助我,我敢打赌你有自己的战斗! – 2014-10-31 03:37:33