多个关系的SQL查询存在于多对多JOIN中

时间:2016-12-15 22:10:57

标签: mysql sql sqlite

MoviesGenres之间存在多对多关系。我想要做的是查询Action Comedy Movies。这跟我一样接近:

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然后我返回一个空表。有一种简单的方法可以用一个查询来完成吗?

4 个答案:

答案 0 :(得分:1)

您需要有关电影的信息,因此SELECT *不合适。以下查询返回与两种类型匹配的影片ID:

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子句计算匹配类型的数量。它假定不再重复类型。
  • 如果您想要完整的电影信息,可以加入使用其他逻辑。

答案 1 :(得分:1)

...试

select COUNT(*) as payer_count, recipient_id
FROM payments
GROUP BY recipient_id
ORDER BY payer_count DESC

答案 2 :(得分: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"
    )
  )
)

答案 3 :(得分: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
    )