【问题标题】:MySQL Searching in Many-to-ManyMySQL 多对多搜索
【发布时间】:2012-11-11 12:59:36
【问题描述】:

我已经开始研究我的第一个 MySQL 数据库,但遇到了一个简单的问题。

我的电影以“多对多”关系按类型分类:

“电影”表 +---------+--------------------+ |movie_id |movie_title | +---------+--------------------+ |1 |印第安纳琼斯 | |2 |死者肖恩 | +---------+--------------------+ “流派”表 +---------+-----------+ |流派 ID |流派名称 | +---------+-----------+ |1 |冒险 | |2 |喜剧 | |3 |恐怖 | +---------+-----------+ 'movie_genres' 表 +---------+---------+ |movie_id |流派_id | +---------+---------+ |1 |1 | |2 |2 | |2 |3 | +---------+---------+

我要做的是按流派搜索我的电影表,并显示每部电影的所有流派,例如:

搜索“恐怖” +------------------+--------------+ |电影名称 |类型名称 | +------------------+--------------+ |死者肖恩 |喜剧,恐怖 | +------------------+--------------+

这是我用来搜索恐怖电影的查询

选择 m.movi​​e_title, GROUP_CONCAT(g.genre_name SEPARATOR ', ') 作为流派名称 FROM 电影 左加入genre_movies gm ON gm.movi​​e_id = m.movi​​e_id LEFT JOIN 流派 g ON g.genre_id = gm.genre_id 按 m.movi​​e_id 分组 有流派名称 LIKE '%horror%'

我遇到的问题是,此查询在过滤之前检索了所有表的全部内容,我认为这是非常低效的。有没有更好的方法可以在显示所有相关类型的同时按一种类型进行搜索?

【问题讨论】:

    标签: mysql search group-by where having


    【解决方案1】:

    试试这个:

    SELECT m.movie_title, A.genre_names
    FROM movies m
    INNER JOIN (SELECT gm.movie_id, GROUP_CONCAT(g.genre_name SEPARATOR ', ') AS genre_names
        FROM genre_movies gm INNER JOIN genres g ON g.genre_id = gm.genre_id
        GROUP BY gm.movie_id) AS A ON m.movie_id = A.movie_id 
    WHERE genre_names LIKE '%horror%'
    

    【讨论】:

    • 嗯,那行得通!谢谢,在我明白你刚刚展示给我的东西之前,我会分开它。
    【解决方案2】:

    为什么不将genre_id 保存在电影表中?

    类似这样的:

    'movies' Table
    +---------+------------+---------------------+
    |movie_id |movie_genre |movie_title          |
    +---------+----------------------------------+
    |1        |1           | Indiana Jones       |
    |2        |2 ,3        | Shaun of the Dead   |
    +---------+----------------------------------+
    

    那么你只需要 2 张桌子。并且您可以轻松过滤查询中的数据。

    我想做的是按类型搜索我的电影表,并显示 每部电影的所有类型,例如:

    可能是这样的:

    SELECT fields FROM table WHERE movie_genre LIKE %movie_genre_id%
    

    【讨论】:

    • 我本来打算做这样的事情,但在听说了标准化,特别是为什么你不应该使用sets(正如我打算那样)之后,我想我应该从右边开始步行并了解多对多表。
    • 猜猜这取决于你想要达到的复杂程度——如果你需要你的记忆,或者如果你有很多很多数据集不适合它。但除此之外,我认为这不是一个大问题——这取决于你。
    • 确实如此。这是一个简单的家庭项目,因此不太可能遇到任何实际问题。虽然我碰巧是一个非常懒惰的程序员,所以我认为当我有时间学习时,我应该尽可能严格地开始,然后在我更舒服地使用该语言时给自己一些余地。 :)
    • 你完全正确。最好使用“正确”的方式——尤其是在学习方面。
    【解决方案3】:
    SELECT m.movie_title, GROUP_CONCAT(g.genre_name SEPARATOR ', ') as genre_names
    FROM  movies m
          INNER JOIN
          (
            SELECT gm.movie_id
            FROM   genre_movies gm 
                   INNER JOIN genres g 
                      ON g.genre_id = gm.genre_id
            WHERE  g.genre_name = 'horror'
            GROUP BY gm.movie_id
          ) a ON a.movie_id = m.movie_id
          INNER JOIN genre_movies gm ON gm.movie_id = m.movie_id
          INNER JOIN genres g ON g.genre_id = gm.genre_id
    GROUP BY m.movie_id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-08
      • 2014-11-26
      • 1970-01-01
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      • 2019-03-07
      相关资源
      最近更新 更多