поиск фильмов с определенными жанрами - PullRequest
0 голосов
/ 15 февраля 2012
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;

Я хочу найти фильмы, которые содержат только жанры «Комедия» и «Ужасы».Когда я запускаю этот запрос, я получаю фильмы, которые являются комедийными и других полов, но я хочу исключить другие полы и получать только фильмы, которые являются только комедиями и ужасами.Любые предложения, пожалуйста?

Ответы [ 3 ]

5 голосов
/ 15 февраля 2012
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: Argh, извините, прочитайте ваш вопрос во второй раз.Обновит запрос через минуту ...

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;

ХотяЯ уверен, что есть более эффективный способ сделать это ...

3 голосов
/ 15 февраля 2012

Если вам нужен только заголовок фильма, ниже должны быть предложены лучшие характеристики.Кажется, что нет необходимости в объединениях в операторе select, и, конечно, нет необходимости оставлять их в внешних соединениях.

SELECT  Title
FROM    Film
WHERE   FilmID IN (SELECT FilmID FROM FilmGenre WHERE Genre IN ('Comedy', 'Horror'))

или в некоторых объединениях СУБД более эффективны, чем подзапросы в выражениях where (*)1004 * Подробнее ... )

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 в зависимости от СУБД для оптимизации.

0 голосов
/ 15 февраля 2012

Попробуйте:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...