[英]SQL query records containing all items in list
我有以下表格:
MOVIE_ID TITLE ---------- ----------------------------- 1 The Shawshank Redemption 2 The Godfather 3 The Godfather: Part II 4 The Dark Knight 5 Pulp Fiction 6 The Good, the Bad and the Ugly 7 Schindler's List 8 Angry Men 9 Fight Club 10 Inception 11 Forrest Gump
DIRECTOR_ID NAME ----------- ------------------------- 1 Tim Robbins 2 Morgan Freeman 3 Marlon Brando 4 Al Pachino 5 Robert De Niro 6 Christian Bale 7 Heath Ledger 8 John Travola 9 Uma Thurman 10 Clint Eastwood 11 Eli Wallach
MOVIE_ID DIRECTOR_ID ---------- ----------- 1 1 1 2 2 3 2 4 3 4 3 5 4 6 4 7 5 8 5 9 6 10
我想要一个查询,返回所有以导演x,y和z为导演的电影:
例:
如果我与Al Pachino和Clint Eastwood一起看电影,它应该什么也不会返回,因为我没有一部以导演和导演兼任的电影。
但是,如果我要和蒂姆·罗宾斯和摩根·弗里曼一起看电影,它应该返回《肖申克的救赎》。
如果无法使用上述设计完成,请提出替代方案。
我已经尝试过,但是我的查询将返回结果:(
SELECT m.title FROM Movie m
WHERE m.movie_id IN (
SELECT d.movie_id FROM Direct d
WHERE d.director_id IN (
SELECT director_id FROM Director dir
WHERE name IN('Clint Eastwood', 'Al Pachino')));
这是实现此目的的一种方法,即对控制器进行分组,过滤和计数:
SELECT m.title
FROM Movie m
INNER JOIN Direct md
on md.movie_id = m.movie_id
INNER JOIN Directors d
on md.director_id = d.director_id
WHERE
d.name IN('Clint Eastwood', 'Al Pachino')
GROUP BY m.title
HAVING COUNT(DISTINCT d.director_id) = 2;
{出于兴趣,电影中的这些演员不是吗?}
使用IN运算符,您的查询将返回具有任何这些导演的电影。
您必须分别检查每位主管:
SELECT *
FROM Movie
WHERE movie_id IN (SELECT movie_id
FROM Direct
WHERE director_id = (SELECT director_id
FROM Directors
WHERE name = 'Clint Eastwood'))
AND movie_id IN (SELECT movie_id
FROM Direct
WHERE director_id = (SELECT director_id
FROM Directors
WHERE name = 'Al Pachino'))
或者,使用复合查询为两位导演构造电影ID列表:
SELECT *
FROM Movie
WHERE movie_id IN (SELECT movie_id
FROM Direct
WHERE director_id = (SELECT director_id
FROM Directors
WHERE name = 'Clint Eastwood')
INTERSECT
SELECT movie_id
FROM Direct
WHERE director_id = (SELECT director_id
FROM Directors
WHERE name = 'Al Pachino'))
或者,从“ Direct
表中获得这两个导演的所有记录,然后按电影分组以能够计算每个电影的导演; 我们需要剩下两个:
SELECT *
FROM Movie
WHERE movie_id IN (SELECT movie_id
FROM Direct
WHERE director_id IN (SELECT director_id
FROM Directors
WHERE name IN ('Clint Eastwood',
'Al Pachino')
GROUP BY movie_id
HAVING COUNT(*) = 2)
最短的一个
;with cte as (
select m.title, ROW_NUMBER() over (partition by m.title order by dir.name) rn
from Movie m
inner join Direct d on m.movie_id = d.movie_id
inner join Director dir on dir.DIRECTOR_ID = d.director_id
where dir.name IN ('Clint Eastwood', 'Al Pachino')
)
select * from cte where rn > 1
您也可以使用SQLite尝试一下:
SELECT title
FROM movie NATURAL JOIN direct NATURAL JOIN directors
GROUP BY title
HAVING GROUP_CONCAT(name) LIKE '%Morgan Freeman%' AND GROUP_CONCAT(name) LIKE '%Tim Robbins%'
;
在这里测试
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.