我有这张桌子:
actors(id: int, first_name: string, last_name: string, gender: string)
directors(id: int, first_name: string, last_name: string)
directors genres(director id: int, genre: string, prob: float)
movies(id: int, name: string, years: int, rank: float)
movies directors(director id: int, movie id: int)
movies genres(movie id: int, genre: string)
roles(actor id: int, movie id: int, role: string)
我想找到2002年威尔逊叶执导的所有喜剧电影中的演员名单。
我正在做以下事情:
select distinct A.first_name,
A.last_name,
M.name
from actors A inner join roles R
on A.id=R.actor_id
inner join movies M
on M.id=R.movie_id
where M.name in ( select M.name
from movies M inner join movies_genres G
on M.id = G.movie_id
inner join movies_directors MD
on M.id = MD.movie_id
inner join directors D
on D.id = MD.director_id
where G.genre = 'Comedy'
and M.year = 2002
and D.first_name='Wilson'
and D.last_name='Yip');
但是,这给了我2002年威尔逊执导的一部喜剧电影中的演员名单,但是我希望演员能够扮演'所有'这样的喜剧。
怎么做?
答案 0 :(得分:0)
首先,让我们找出数量: 2002年由Wilson Yip执导的喜剧。我们正在这样做,以确定哪些演员在所有演员中演出(后来):
declare @totalNumberOfMovies as int =(
Select count(*)
from
movies m
inner join
movies_genres mg
on m.movie_id=mg.movied_id
inner join movies_directors md
on mg.movie_id=md.movie_id
inner join directors d
on md.director_id=d.director_id
where mg.genre='Comedy' and d.first_name='Wilson' and d.last_name='Yip' and m.year='2002'
);
由Wilson Yip在2002年执导的喜剧总数已分配给变量。
现在,你必须加入你需要的所有表(包括所有过滤器),按行者的名字和姓氏分组,并包括“有计数(*)”过滤器,其值必须等于先前定义的变量@totalNumberOfMovies
它只会让你扮演所有电影的演员。而不是使用变量,你可以使用子查询。
问候; - )
答案 1 :(得分:0)
您可以使用子查询计算此类电影的数量,并将其放入having
子句中,例如:
select a.first_name, a.last_name, m.name
from (select r.actor_id
from movies M
join movies_genres G
on M.id = G.movie_id
join movies_directors MD
on M.id = MD.movie_id
join directors D
on D.id = MD.director_id
join roles r
on r.movie_id = m.id
group by r.actor_id
having count(*) = (select count(*) as num_of_movies
from movies M
join movies_genres G
on M.id = G.movie_id
join movies_directors MD
on M.id = MD.movie_id
join directors D
on D.id = MD.director_id
where G.genre = 'Comedy'
and M.year = 2002
and D.first_name = 'Wilson'
and D.last_name = 'Yip')) x
join actors a
on a.id = x.actor_id
join roles r
on a.id = r.actor_id
join movies m
on m.id = r.movie_id
或者,您可以将该子查询作为from
放入inline view
子句中,并将其连接到另一个内联视图,其中计算每个actor的计数,然后将其连接回原始表中你想要的字段,如:
select a.first_name, a.last_name, m.name
from (select r.actor_id, count(*) as movies_this_actor
from movies M
join movies_genres G
on M.id = G.movie_id
join movies_directors MD
on M.id = MD.movie_id
join directors D
on D.id = MD.director_id
join roles r
on r.movie_id = m.id
group by r.actor_id) x
join (select count(*) as movies_total
from movies M
join movies_genres G
on M.id = G.movie_id
join movies_directors MD
on M.id = MD.movie_id
join directors D
on D.id = MD.director_id
where G.genre = 'Comedy'
and M.year = 2002
and D.first_name = 'Wilson'
and D.last_name = 'Yip') y
on x.movies_this_actor = y.movies_total
join actors a
on a.id = x.actor_id
join roles r
on a.id = r.actor_id
join movies m
on m.id = r.movie_id
答案 2 :(得分:0)
这个SQL可以进行优化,但粗略地说,如果你使用的是Oracle,你可以尝试类似下面的内容。
with wilson_yip_2002_comedies as
(
select m.id
from movies m, movies_genres mg, movies_directors md, directors d
where m.id = mg.movie_id
and m.id = md.movie_id
and md.director_id = d.id
and mg.genre = 'Comedy'
and m.years = 2002
and d.first_name = 'Wilson'
and d.last_name = 'Yip'
)
select a.id, a.first_name, a.last_name, count(r.movie_id) n_movies
from actors a, roles r, wilson_yip_2002_comedies
where a.id = r.actor_id
and r.movie_id = wilson_yip_2002_comedies.id
group by a.id, a.first_name, a.last_name
having count(r.movie_id) = (
select count(1)
from wilson_yip_2002_comedies);
步骤:
如果你不能使用WITH,你可以写两次整个查询,虽然这不是很整洁。
请尝试提供一种简单的方法来尽可能地重现您的问题,例如SQLFiddle。
http://sqlfiddle.com/#!4/4b05c/5
希望这有帮助。