首页 > 解决方案 > SQL 多对多过滤掉项目而不是包含

问题描述

所以我正在构建一个应用程序,其中一个元素是搜索电影。数据存储在关系数据库中。

过滤条件之一是流派。电影可以有多种类型,所以它是多对多的关系。除了通常的标签示例之外,过滤器的工作方式并不完全相同。

假设您有一部纪录片,其中包含流派documentarysports. 如果我对纪录片感兴趣但对体育不感兴趣,我很可能对体育相关的纪录片不感兴趣。如果我像通常使用标签一样实现查询,则查询如下所示:

select distinct(m.id) from movies m
  join genres_movies gm.movie_id = m.id
  join genres on gm.genre_id = g.id
  where genre.name in ('documentary', 'action', 'horror')

通过这个查询,我会得到上面提到的体育纪录片。那么如何排除所有具有某种类型的电影呢?

标签: sqlmany-to-many

解决方案


我认为存在和“不存在”是你需要的

select distinct(m.id) from movies m
 where exists (select 1 
                 from genres g 
                 join genres_movies gm 
                   on gm.genre_id = g.id
                where gm.movie_id = m.id
                  and name in ('documentary', 'action', 'horror'))
   and not exists (select 1 
                     from genres g 
                     join genres_movies gm  
                       on gm.genre_id = g.id
                    where gm.movie_id = m.id
                      and g.name not in ('sports', 'drama'))

推荐阅读