select
film.title
from film
left outer join filmitem ON film.filmid = filmitem.filmid
left outer join filmgenre ON filmitem.filmid = filmgenre.filmid
where
film.title = title and filmgenre.genre NOT IN (
select genre from genre
where genre != 'Comedy' and genre != 'Horror')
group by title;
我想找到只包含“Comedy”和“Horror”类型的电影。当我运行这个查询时,我会看到喜剧和其他性别的电影,但我想排除其他性别,只得到只有喜剧和恐怖的电影。有什么建议吗?
答案 0 :(得分:5)
select
film.title
from film
left outer join filmitem ON film.filmid = filmitem.filmid
left outer join filmgenre ON filmitem.filmid = filmgenre.filmid
where
film.title = title and filmgenre.genre IN ('Comedy', 'Horror')
group by title;
UPD:对不起,第二次读你的问题。将在一分钟内更新查询...
UPD2:如果你需要选择只有'喜剧'和'恐怖'两种类型的电影,你可以使用
select
film.title
from film
left outer join filmitem ON film.filmid = filmitem.filmid
where
film.title = title
AND EXISTS (SELECT * FROM filmgenre fg WHERE filmitem.filmid = fg.filmid AND fg.genre='Comedy')
AND EXISTS (SELECT * FROM filmgenre fg WHERE filmitem.filmid = fg.filmid AND fg.genre='Horror')
AND NOT EXISTS (SELECT * FROM filmgenre fg WHERE filmitem.filmid = fg.filmid AND fg.genre NOT IN ('Comedy','Horror'))
group by title;
虽然我很确定有更有效的方法来做到这一点......
答案 1 :(得分:3)
如果你只需要电影名称,下面应该提供最好的表现。似乎没有必要在select语句中使用连接,当然也不需要将它们留在外连接中。
SELECT Title
FROM Film
WHERE FilmID IN (SELECT FilmID FROM FilmGenre WHERE Genre IN ('Comedy', 'Horror'))
或在某些RDBMS联接中比where子句中的子查询更有效(Read more...)
SELECT Film.Title
FROM Film
INNER JOIN
( SELECT FilmID
FROM FilmGenre
WHERE Genre IN ('Comedy', 'Horror')
GROUP BY FilmID
) g
ON g.FileID = Film.FilmID
编辑:
如果需要的是只有喜剧和恐怖片的影片那么你需要的东西是:
SELECT Film.Title
FROM Film
INNER JOIN
( SELECT FilmID
FROM FilmGenre
GROUP BY FilmID
HAVING COUNT(DISTINCT CASE WHEN Genre IN ('Comedy', 'Horror') THEN Genre END) = 2
AND COUNT(DISTINCT Genre) = 2
) g
ON g.FileID = Film.FilmID
同样的逻辑仍然适用于将子查询移动到IN子句,具体取决于RDBMS以进行优化。
答案 2 :(得分:0)
尝试:
select title from film f
where not exists
(select null
from filmgenre g
where f.filmid = g.filmid and
g.genre NOT IN ('Comedy', 'Horror')
)
(假设电影中至少会有一种类型。)
编辑:或者,如果可能有未分配到任何类型的电影,请尝试:
select max(f.title) title
from film f
join filmgenre g on f.filmid = g.filmid
group by f.filmid
having count(distinct g.genre) =
count(distinct case when g.genre in ('Comedy', 'Horror') then g.genre end)