2016-12-15 222 views
0

我在MoviesGenres之间有多对多的关系。我想要做的是查询ActionComedyMovies。这与我已经接近:SQL查询多重关系存在于多对多JOIN中

SELECT * FROM movies 
JOIN movies_genre ON (movies.id = movies_genre.movie_id) 
JOIN genres ON (movies_genre.genre_id = genres.id) 
WHERE (
    genres.genre = "Comedy" OR 
    genres.genre = "Action & Adventure" 
) 

但是,这给了我所有的喜剧或冒险电影。如果我将OR更改为AND,则返回空表。有一个简单的方法来做到这一点与一个查询?

回答

1

你想要关于电影的其他信息,所以SELECT *是不合适的。下面的查询返回匹配,这两个流派的电影IDS:

SELECT mg.movie_id 
FROM movies_genre mg JOIN 
    genres g 
    ON mg.genre_id = g.id 
WHERE g.genre IN ('Comedy', 'Action & Adventure') 
GROUP BY mg.movie_id 
HAVING COUNT(*) = 2; 

注:

  • 表的别名使查询更容易编写和阅读。
  • IN比一堆OR表达式更明智。
  • HAVING子句用于统计匹配流派的数量。它假定流派不重复。
  • 如果您想获得完整的影片信息,那么您可以使用附加的逻辑加入。
+0

唯一的问题是,它可能是一部电影是动作爱情喜剧。所以'有计数(*)> = 2'似乎更好。 –

+0

@ChaseRoberts。 。 。看看'WHERE'子句。 –

0

我发现一些作品,但不能这样做,我相信这是最好的方法:

SELECT * FROM movies 
JOIN movies_genre ON (movies.id = movies_genre.movie_id) 
JOIN genres ON (movies_genre.genre_id = genres.id) 
WHERE (
    genres.genre = "Action" 
    AND (
    movies.poster IN (
    SELECT movies.poster FROM movies 
    JOIN movies_genre ON (movies.id = movies_genre.id) 
    JOIN genres ON (movies_genre.id = genres.id) 
    WHERE genres.genre = "Comedy" 
    ) 
) 
) 
0

唉,很多一对多关系是最糟糕的,需要这样的疑问:

select * 
from movies as m 
where exists (
    select 1 
    from movies_genre as mg 
    inner join genres as g 
    on g.id = mg.genre_id 
    where mg.movie_id = m.id 
    and g.genre in ('Action & Adventure', 'Comedy') 
    group by g.id 
    having count(*) = 2 
    ) 
1

尝试...

select * from movies m 
where m.id in (select movie_id from movies_genre join genres on (movies_genere.genre_id = genres.id) where genres.genre = 'Comedy') 
and m.id in (select movie_id from movies_genre join genres on (movies_genere.genre_id = genres.id) where genres.genre = 'Action & Adventure')