sql查找具有特定类型的电影

时间:2012-02-15 13:20:51

标签: sql postgresql

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”类型的电影。当我运行这个查询时,我会看到喜剧和其他性别的电影,但我想排除其他性别,只得到只有喜剧和恐怖的电影。有什么建议吗?

3 个答案:

答案 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)