【问题标题】:How can I search for a movie based on its genre where genre is stored in a many-to-many table如何根据流派存储在多对多表中的流派搜索电影
【发布时间】:2014-11-03 22:08:42
【问题描述】:

我需要从表 movie wheregenre.name="action" 中获取所有列

我有一张表genre,它有genre.id 和genre.name

我有另一个表movie2genre,它有movieId 和genreId

要按电影 ID 获取流派列表,我可以执行以下操作

SELECT name FROM movie2genre
JOIN Genre on Genre.id = movie2genre.GenreId 
JOIN Movie on Movie.id = movie2genre.MovieId 
WHERE Movie.id = 15664

但我不知道如何按流派名称获取电影列表

例如,从类型为“动作”或“惊悚片”的电影中选择全部

编辑。

我需要一个适用于'action' OR 'thriller''action' AND 'thriller' 的查询

【问题讨论】:

  • 相同的查询...只是where Genre.Name = 'action',您还需要将您的选择修改为movie.name。

标签: mysql sql


【解决方案1】:

试试这个,它应该可以工作!


SELECT 
    m.* 
FROM 
    Movie m
    inner join movie2genre  mg on m.MovieId = mg.MovieId
    inner join Genre g         on g.GenreId = mg.GenreId 
WHERE
    g.name = 'action' or g.name='thriller'

【讨论】:

  • 即使我有一个名为电影Error Code: 1051. Unknown table 'movie' 的表,我也收到错误消息@
  • 使用别名 Movie m 时,SELECT 必须是 SELECT m.*
  • 试试 'select m.*',只是拼错了
  • 那是因为如果 g.name = 'action' 它不能也是 ='thriller'。那没有意义。使用 'AND' 你应该比较不同的东西,例如 g.name = 'action' 和 m.name like '%Night%'
  • 如果一部电影可以有多个分类,您可以在 where 子句中使用子查询来实现它。
【解决方案2】:

OR 的情况很简单,您可以将其作为许多已显示的连接,或作为 EXISTS。 AND 案例很棘手,因为您必须检查两个不同的行。您可以使用两个存在子句。

和...

SELECT name 
FROM Movie 
Where 
EXISTS (
 select *
 from movie2genre 
 JOIN Genre on Genre.id = movie2genre.GenreId 
 where Movie.id = movie2genre.MovieId 
   and genre = 'action'
)
and
EXISTS (
 select *
 from movie2genre 
 JOIN Genre on Genre.id = movie2genre.GenreId 
 where Movie.id = movie2genre.MovieId 
   and genre = 'thriller'
)

或者...

SELECT name 
FROM Movie 
Where 
EXISTS (
 select *
 from movie2genre 
 JOIN Genre on Genre.id = movie2genre.GenreId 
 where Movie.id = movie2genre.MovieId 
   and genre in ('action', 'thriller')
)

另一种方法是计算有多少movie2genre 匹配(使用OR 方法)。如果数字大于零,则满足 OR。如果数量等于所有可能的流派,则 AND 也满足。

【讨论】:

    【解决方案3】:

    我错过了什么吗?

    SELECT movie.name FROM movie2genre
    JOIN Genre on Genre.id = movie2genre.GenreId 
    JOIN Movie on Movie.id = movie2genre.MovieId 
    WHERE Genre.Name ='Action'
    

    更新

    要执行 AND 子句,请使用

          select name
    from m
    inner join mg on mg.movieid = m.movieid
    inner join g on g.genreid = mg.genreid
    where
    g.genre = 'Action' or g.genre='Thriller'
    group by name
    having count(1) >= CASE WHEN OrClause then 1 else NumberOfGenresSupplied end
    

    所以在这种情况下 numberofGenresSupplied 将等于 2(您可以从提交的表单中得出)。 如果您想要任何匹配的流派,OrClause 将设置为 true,如果它必须匹配每个匹配的流派,则设置为 false。

    这将确保符合您的类型标准的不同电影列表。

    【讨论】:

    • 这对WHERE Genre.Name ='Action' AND genre.name = 'thriller' 有效,但不适用于WHERE Genre.Name ='Action' AND genre.name = 'thriller',因为一部电影可以有多个类型
    【解决方案4】:

    您可以只使用 WHERE 子句过滤流派,就像过滤电影 ID 一样。试试这个:

    SELECT movie.name
    FROM movie2genre
    JOIN genre ON genre.id = movie2genre.genreid
    JOIN movie ON movie.id = movie2genre.movieid
    WHERE genre = 'action' OR genre = 'thriller';
    

    编辑 如果您想使用 AND 来获取两种类型,您可以执行相同的连接,按电影 ID 分组并过滤 2 行。试试这个:

    SELECT movie.name
    FROM movie2genre
    JOIN genre ON genre.id = movie2genre.genreid
    JOIN movie on movie.id = movie2genre.movieid
    WHERE genre = 'action' OR genre = 'thriller'
    GROUP BY movie.id
    HAVING COUNT(*) = 2;
    

    【讨论】:

    • 一部电影可以有两种类型吗?
    • @code578841441 我刚刚看到你的编辑,请看我的编辑。
    猜你喜欢
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多