我正在完成一项任务,我需要找一些由导演执导的电影,这些电影导演多部影片由安吉丽娜朱莉主演。目前,我有这个:
SELECT DISTINCT t.title, n.name
FROM (
SELECT DISTINCT t.id theMovies
FROM name n
INNER JOIN cast_info c
ON (c.person_id = n.id)
INNER JOIN title t
ON (t.id = c.movie_id)
WHERE n.name = 'Jolie, Angelina'
) as newTable
INNER JOIN title t
ON (t.id = theMovies)
INNER JOIN cast_info c
ON (c.movie_id = t.id)
INNER JOIN name n
ON (n.id = c.person_id)
CROSS JOIN role_type
WHERE role = 'director';
此查询目前所做的是查找由Angelina Jolie主演的电影列表,然后列出这些电影的导演。我现在需要做的就是只保留导演所在的行至少另一行。有小费吗? 作为参考,这是我正在使用的数据库的图表: http://i.imgur.com/kj8qVgF.png 我对SQL也很陌生,所以任何改进我的查询的建议都会非常感激!
答案 0 :(得分:2)
我会将其分解为几个部分并构建到您的最终查询。如果你是新手 SQL,将事物分解成一些东西并将它们重新组合在一起是一种很好的做法。有了这个,我将重申一下目标:找一些由安吉丽娜·朱莉导演电影的导演导演的电影。
我首先要拍摄安吉丽娜朱莉的所有电影:
SELECT t.id
FROM name n
JOIN cast_info c ON c.person_id = n.id
JOIN title t ON t.id = c.movie_id
WHERE n.name = 'Jolie, Angelina';
现在,让我们来看看这些电影的导演:
SELECT c.person_id
FROM cast_info c
JOIN title t ON t.id = c.movie_id
JOIN role_type r ON r.id = c.role_id
WHERE r.role = 'director' AND t.id IN(SELECT t.id
FROM name n
JOIN cast_info c ON c.person_id = n.id
JOIN title t ON t.id = c.movie_id
WHERE n.name = 'Jolie, Angelina');
我们可以将上述查询修改为按person_id分组,其计数(*)大于一(表示多部电影)。
SELECT c.person_id
FROM cast_info c
JOIN title t ON t.id = c.movie_id
JOIN role_type r ON r.id = c.role_id
WHERE r.role = 'director' AND t.id IN(SELECT t.id
FROM name n
JOIN cast_info c ON c.person_id = n.id
JOIN title t ON t.id = c.movie_id
WHERE n.name = 'Jolie, Angelina')
GROUP BY person_id
HAVING COUNT(*) > 1;
现在,我们需要查找这些导演指导的电影,并进行过滤,以便我们不会包含安吉丽娜朱莉的电影。
SELECT t.id
FROM title t
JOIN cast_info c ON c.movie_id = t.id
JOIN role_type r ON r.id = c.role_id
WHERE r.role = 'director'
AND c.person_id IN (SELECT c.person_id
FROM cast_info c
JOIN title t ON t.id = c.movie_id
JOIN role_type r ON r.id = c.role_id
WHERE r.role = 'director' AND t.id IN(SELECT t.id
FROM name n
JOIN cast_info c ON c.person_id = n.id
JOIN title t ON t.id = c.movie_id
WHERE n.name = 'Jolie, Angelina')
GROUP BY person_id
HAVING COUNT(*) > 1)
AND t.id NOT IN(SELECT t.id
FROM name n
JOIN cast_info c ON c.person_id = n.id
JOIN title t ON t.id = c.movie_id
WHERE n.name = 'Jolie, Angelina');
我无法通过SQL Fiddle进行测试,因为它目前无法正常工作,但我会尽快这样做。有些东西可能需要调整,但请告诉我这是否有帮助。
答案 1 :(得分:0)
请尝试:
SELECT
t.title
, n.name
FROM title t
INNER JOIN cast_info c
ON t.id = c.movie_id
INNER JOIN name n
ON c.person_id = n.id
INNER JOIN role_type r
ON c.person_role_id = r.id
INNER JOIN (
SELECT
c.person_id
, r.id
FROM cast_info c
INNER JOIN role_type r
ON c.person_role_id = r.id
WHERE r.role = 'director'
AND c.movie_id IN (
SELECT DISTINCT
c.movie_id
FROM name n
INNER JOIN cast_info c
ON c.person_id = n.id
WHERE n.name = 'Jolie, Angelina'
)
GROUP BY
c.person_id
, r.id
HAVING COUNT(*) > 1
) d
ON c.person_id = d.person_id
AND r.id = d.id
;
尝试多部分查询"部分"如果它似乎不起作用,这有助于确定它可能失败的地方
-- 1
SELECT DISTINCT
c.movie_id
FROM name n
INNER JOIN cast_info c
ON c.person_id = n.id
WHERE n.name = 'Jolie, Angelina'
;
-- 2
SELECT
c.person_id
, r.id
FROM cast_info c
INNER JOIN role_type r
ON c.person_role_id = r.id
WHERE r.role = 'director'
GROUP BY
c.person_id
, r.id
HAVING COUNT(*) > 1
;
-- 3
SELECT
c.person_id
, r.id
FROM cast_info c
INNER JOIN role_type r
ON c.person_role_id = r.id
WHERE r.role = 'director'
AND c.movie_id IN (
SELECT DISTINCT
c.movie_id
FROM name n
INNER JOIN cast_info c
ON c.person_id = n.id
WHERE n.name = 'Jolie, Angelina'
)
GROUP BY
c.person_id
, r.id
HAVING COUNT(*) > 1
;