2017-03-05 64 views
0

我正在处理3个表格:actors,films和actor_film。演员和电影只有2个字段:id(主键)和名字。 Actor_film也有两个字段,演员和电影,这两个字段分别代表演员和电影ID。所以如果一部电影里面有4个演员,就会有4部actor_film条目和4部不同的演员。嵌套SELECT语句重复条目和COUNT

我的问题是,鉴于某个演员的ID,我想返回该电影中的演员ID,演员姓名,电影名称和演员总数。但是,我想要展示的唯一演员是包含某些字母的演员。

让我通过一个例子来说明问题。说汤姆汉克斯只有两部电影,阿甘正传和拯救大兵瑞恩,而且我正在寻找那些两部电影中名字中都有“加里”或“马特”的演员。进一步假设在阿甘正传中有4个演员,在Saving Private Ryan中有5个演员。然后,我唯一会想回报将是(没有列名,当然)

actor id | actor name | film name   | # actors 
abcdefg | Gary Sinise | Forrest Gump  | 4 
hijklmn | Matt Damon | Saving Private Ryan | 5 
opqrstu | Paul Giamatti | Saving Private Ryan | 5 

目前,我对那里的方式75%通过:

SELECT actor.id, actors.name, films.name, 
FROM (
    SELECT actor_film.film 
    FROM actor_film, actors 
    WHERE actor_film.actor = actors.id 
) AS a, actor_film, actors, films 
WHERE actor_film.film = a.film 
    AND actors.id = actor_film.actor 
    AND films.id = a.film; 

这是返回的东西,如:

arnie | Arnold Schwarzenegger | Around the World in 80 Days 
arnie | Arnold Schwarzenegger | Around the World in 80 Days 

对于有2个演员在其中的电影。换句话说,我无法将电影中所有不同的演员都拉出来,但隐含地明确地指出了这一点,并且没有明确地使用COUNT

无论如何,我想我正在寻找某种INNER JOIN或嵌套SELECT,但我是SQLite3的新手,不知道如何将它们结合在一起。任何解决方案都会很棒,而且最重要的解释也会很棒。

回答

0

您不应该使用旧式连接。他们在95年年纪较大时,允许你做更加清晰的新标准被制定为标准。

我注意到,你也可以使用复数为你的表名(例如,“演员”)的标准样式是用奇异的表的表名(例如,“演员”)

我用这两个建议下面,我也告诉你每一步。我建议你运行每个步骤的查询并查看输出,以便了解因为您是SQL新手而一切正常。

好吧,让我们一步一步的问题。首先要看到每个演员和电影他们在(你的前3列)做到这一点:

SELECT a.id as actor_id, a.name as actor_name, f.name as film_name 
FROM actor as a 
JOIN actor_film af on a.id = af.actor 
JOIN film as f on af.film = f.id 

你的最后一栏可以用下面的查询中找到:

SELECT af.film as film_id, count(*) as c 
FROM actor_film as af 
GROUP BY af.film 

现在我们只它们连接在一起

SELECT a.id as actor_id, a.name as actor_name, f.name as film_name, fc.c as num_actors 
FROM actor as a 
JOIN actor_film af on a.id = af.actor 
JOIN film as f on af.film = f.id 
JOIN (
    SELECT af.film as film_id, count(*) as c 
    FROM actor_file as af 
    GROUP BY af.film 
) as fc on af.film = fc.film_id 

如果你愿意,你可以添加一个

WHERE a.name = 'Gary' OR a.name = 'Matt' 

取决于您可能需要的平台

WHERE lower(a.name) = 'gary' OR lower(a.name) = 'matt' 
+0

谢谢!如果我想进一步只显示其名字包含某些字母的演员,我会在那里放置?在第一个JOIN? – ohjava

+0

@ohjava - 我为你放了一个where子句的例子。 – Hogan